More ktor parity work
This commit is contained in:
parent
e84dedf675
commit
eff486898f
35 changed files with 295 additions and 43 deletions
|
@ -1,23 +1,18 @@
|
||||||
apply plugin: 'java'
|
plugins {
|
||||||
apply plugin: 'application'
|
id 'java'
|
||||||
apply plugin: "io.spring.dependency-management"
|
id 'application'
|
||||||
apply plugin: "org.springframework.boot"
|
id "io.spring.dependency-management"
|
||||||
|
id "org.springframework.boot"
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-security"
|
|
||||||
implementation "org.springframework.session:spring-session-jdbc"
|
|
||||||
implementation "org.springframework.boot:spring-boot-starter-web"
|
implementation "org.springframework.boot:spring-boot-starter-web"
|
||||||
runtimeOnly "org.postgresql:postgresql:42.2.23"
|
implementation "org.springframework.boot:spring-boot-starter-security"
|
||||||
testImplementation "org.springframework.boot:spring-boot-starter-test"
|
testImplementation "org.springframework.boot:spring-boot-starter-test"
|
||||||
testImplementation "org.springframework.security:spring-security-test:5.1.5.RELEASE"
|
testImplementation "org.springframework.security:spring-security-test"
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
|
||||||
description = "twigs"
|
|
||||||
}
|
|
||||||
|
|
||||||
mainClassName = "com.wbrawner.twigs.TwigsServerApplication"
|
|
||||||
|
|
||||||
sourceCompatibility = 17
|
sourceCompatibility = 17
|
||||||
targetCompatibility = 17
|
targetCompatibility = 17
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.wbrawner.twigs.session.SessionResponse;
|
||||||
import com.wbrawner.twigs.session.UserSessionRepository;
|
import com.wbrawner.twigs.session.UserSessionRepository;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
@ -34,6 +35,7 @@ public class UserController {
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final UserPermissionRepository userPermissionsRepository;
|
private final UserPermissionRepository userPermissionsRepository;
|
||||||
private final UserSessionRepository userSessionRepository;
|
private final UserSessionRepository userSessionRepository;
|
||||||
|
private final UserService userService;
|
||||||
private final DaoAuthenticationProvider authenticationProvider;
|
private final DaoAuthenticationProvider authenticationProvider;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -43,13 +45,14 @@ public class UserController {
|
||||||
UserSessionRepository userSessionRepository,
|
UserSessionRepository userSessionRepository,
|
||||||
PasswordEncoder passwordEncoder,
|
PasswordEncoder passwordEncoder,
|
||||||
UserPermissionRepository userPermissionsRepository,
|
UserPermissionRepository userPermissionsRepository,
|
||||||
DaoAuthenticationProvider authenticationProvider
|
UserService userService, DaoAuthenticationProvider authenticationProvider
|
||||||
) {
|
) {
|
||||||
this.budgetRepository = budgetRepository;
|
this.budgetRepository = budgetRepository;
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
this.userSessionRepository = userSessionRepository;
|
this.userSessionRepository = userSessionRepository;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.userPermissionsRepository = userPermissionsRepository;
|
this.userPermissionsRepository = userPermissionsRepository;
|
||||||
|
this.userService = userService;
|
||||||
this.authenticationProvider = authenticationProvider;
|
this.authenticationProvider = authenticationProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,17 +78,13 @@ public class UserController {
|
||||||
|
|
||||||
@PostMapping(path = "/login", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(path = "/login", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
ResponseEntity<SessionResponse> login(@RequestBody LoginRequest request) {
|
ResponseEntity<SessionResponse> login(@RequestBody LoginRequest request) {
|
||||||
var authReq = new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword());
|
|
||||||
Authentication auth;
|
|
||||||
try {
|
try {
|
||||||
auth = authenticationProvider.authenticate(authReq);
|
return ResponseEntity.ok(new SessionResponse(
|
||||||
|
userService.login(request.getUsername(), request.getPassword())
|
||||||
|
));
|
||||||
} catch (AuthenticationException e) {
|
} catch (AuthenticationException e) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||||
}
|
}
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
|
||||||
var user = Objects.requireNonNull(getCurrentUser());
|
|
||||||
var session = userSessionRepository.save(new Session(user.getId()));
|
|
||||||
return ResponseEntity.ok(new SessionResponse(session));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/me", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@GetMapping(path = "/me", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
spring.datasource.url=jdbc:postgresql://localhost:5432/twigs
|
spring.datasource.url=jdbc:h2:./twigs.db
|
||||||
spring.datasource.username=twigs
|
|
||||||
spring.datasource.password=twigs
|
|
||||||
spring.profiles.active=prod
|
spring.profiles.active=prod
|
||||||
spring.session.jdbc.initialize-schema=always
|
spring.session.jdbc.initialize-schema=always
|
||||||
spring.datasource.testWhileIdle=true
|
twigs.cors.domains=http://localhost:4200
|
||||||
spring.datasource.timeBetweenEvictionRunsMillis=60000
|
|
||||||
spring.datasource.validationQuery=SELECT 1
|
|
||||||
twigs.cors.domains=*
|
|
||||||
logging.level.org.springframework.security=DEBUG
|
logging.level.org.springframework.security=DEBUG
|
||||||
|
|
25
app/build.gradle
Normal file
25
app/build.gradle
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'application'
|
||||||
|
id "io.spring.dependency-management"
|
||||||
|
id "org.springframework.boot"
|
||||||
|
id 'org.graalvm.buildtools.native' version '0.9.18'
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
implementation project(':api')
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-security"
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-web"
|
||||||
|
implementation "org.springframework.session:spring-session-jdbc"
|
||||||
|
runtimeOnly 'org.postgresql:postgresql:42.2.27'
|
||||||
|
runtimeOnly 'com.h2database:h2:2.2.220'
|
||||||
|
testImplementation "org.springframework.boot:spring-boot-starter-test"
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
description = "twigs"
|
||||||
|
}
|
||||||
|
|
||||||
|
mainClassName = "com.wbrawner.twigs.TwigsServerApplication"
|
|
@ -1,6 +1,6 @@
|
||||||
package com.wbrawner.twigs.config;
|
package com.wbrawner.twigs.config;
|
||||||
|
|
||||||
import com.wbrawner.twigs.passwordresetrequest.PasswordResetRequestRepository;
|
import com.wbrawner.twigs.user.PasswordResetRequestRepository;
|
||||||
import com.wbrawner.twigs.session.UserSessionRepository;
|
import com.wbrawner.twigs.session.UserSessionRepository;
|
||||||
import com.wbrawner.twigs.user.UserRepository;
|
import com.wbrawner.twigs.user.UserRepository;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -11,7 +11,6 @@ import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.provisioning.JdbcUserDetailsManager;
|
import org.springframework.security.provisioning.JdbcUserDetailsManager;
|
||||||
|
@ -80,10 +79,12 @@ public class SecurityConfig {
|
||||||
return httpSecurity.authorizeHttpRequests((authz) -> {
|
return httpSecurity.authorizeHttpRequests((authz) -> {
|
||||||
try {
|
try {
|
||||||
authz
|
authz
|
||||||
.requestMatchers("/api/users/register", "/api/users/login")
|
.requestMatchers(
|
||||||
.permitAll()
|
"/api/^(users/register|users/login)"
|
||||||
.anyRequest()
|
)
|
||||||
.authenticated()
|
.authenticated()
|
||||||
|
.anyRequest()
|
||||||
|
.permitAll()
|
||||||
.and()
|
.and()
|
||||||
.httpBasic()
|
.httpBasic()
|
||||||
.authenticationEntryPoint(new SilentAuthenticationEntryPoint())
|
.authenticationEntryPoint(new SilentAuthenticationEntryPoint())
|
||||||
|
@ -111,9 +112,7 @@ public class SecurityConfig {
|
||||||
.and()
|
.and()
|
||||||
.csrf()
|
.csrf()
|
||||||
.disable()
|
.disable()
|
||||||
.addFilter(new TokenAuthenticationFilter(authenticationManager))
|
.addFilter(new TokenAuthenticationFilter(authenticationManager));
|
||||||
.sessionManagement()
|
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.wbrawner.twigs.config;
|
package com.wbrawner.twigs.config;
|
||||||
|
|
||||||
|
import com.wbrawner.twigs.Utils;
|
||||||
import com.wbrawner.twigs.session.UserSessionRepository;
|
import com.wbrawner.twigs.session.UserSessionRepository;
|
||||||
import com.wbrawner.twigs.user.UserRepository;
|
import com.wbrawner.twigs.user.UserRepository;
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
@ -47,7 +48,7 @@ public class TokenAuthenticationProvider extends DaoAuthenticationProvider {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
// Update the session on a background thread to avoid holding up the request longer than necessary
|
// Update the session on a background thread to avoid holding up the request longer than necessary
|
||||||
var updatedSession = session.get();
|
var updatedSession = session.get();
|
||||||
updatedSession.setExpiration(twoWeeksFromNow());
|
updatedSession.setExpiration(Utils.twoWeeksFromNow());
|
||||||
userSessionRepository.save(updatedSession);
|
userSessionRepository.save(updatedSession);
|
||||||
}).start();
|
}).start();
|
||||||
return new SessionAuthenticationToken(
|
return new SessionAuthenticationToken(
|
22
app/src/main/java/com/wbrawner/twigs/config/WebConfig.java
Normal file
22
app/src/main/java/com/wbrawner/twigs/config/WebConfig.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//package com.wbrawner.twigs.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
//import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
|
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
//
|
||||||
|
//@Configuration
|
||||||
|
//public class WebConfig implements WebMvcConfigurer {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
|
// registry.addViewController("/").setViewName("forward:/index.html");
|
||||||
|
// registry.addViewController("/{path:\\w*}").setViewName("forward:/index.html");
|
||||||
|
// registry.addViewController("/(^api)/**").setViewName("forward:/index.html");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
// registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/");
|
||||||
|
// }
|
||||||
|
//}
|
12
core/build.gradle
Normal file
12
core/build.gradle
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'application'
|
||||||
|
id "io.spring.dependency-management"
|
||||||
|
id "org.springframework.boot"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-security"
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-web"
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.wbrawner.twigs.budget;
|
package com.wbrawner.twigs.budget;
|
||||||
|
|
||||||
|
import com.wbrawner.twigs.Utils;
|
||||||
import com.wbrawner.twigs.category.Category;
|
import com.wbrawner.twigs.category.Category;
|
||||||
import com.wbrawner.twigs.transaction.Transaction;
|
import com.wbrawner.twigs.transaction.Transaction;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
@ -15,7 +16,7 @@ import static com.wbrawner.twigs.Utils.randomId;
|
||||||
@Entity
|
@Entity
|
||||||
public class Budget {
|
public class Budget {
|
||||||
@Id
|
@Id
|
||||||
private String id = randomId();
|
private String id = Utils.randomId();
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
private String currencyCode;
|
private String currencyCode;
|
|
@ -0,0 +1,127 @@
|
||||||
|
package com.wbrawner.twigs.recurringtransaction;
|
||||||
|
|
||||||
|
import com.wbrawner.twigs.budget.Budget;
|
||||||
|
import com.wbrawner.twigs.category.Category;
|
||||||
|
import com.wbrawner.twigs.user.User;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import static com.wbrawner.twigs.Utils.randomId;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class RecurringTransaction implements Comparable<RecurringTransaction> {
|
||||||
|
@Id
|
||||||
|
private final String id = randomId();
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(nullable = false)
|
||||||
|
private final User createdBy;
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
private Instant date;
|
||||||
|
private Long amount;
|
||||||
|
@ManyToOne
|
||||||
|
private Category category;
|
||||||
|
private Boolean expense;
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(nullable = false)
|
||||||
|
private Budget budget;
|
||||||
|
|
||||||
|
public RecurringTransaction() {
|
||||||
|
this(null, null, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecurringTransaction(
|
||||||
|
String title,
|
||||||
|
String description,
|
||||||
|
Instant date,
|
||||||
|
Long amount,
|
||||||
|
Category category,
|
||||||
|
Boolean expense,
|
||||||
|
User createdBy,
|
||||||
|
Budget budget
|
||||||
|
) {
|
||||||
|
this.title = title;
|
||||||
|
this.description = description;
|
||||||
|
this.date = date;
|
||||||
|
this.amount = amount;
|
||||||
|
this.category = category;
|
||||||
|
this.expense = expense;
|
||||||
|
this.createdBy = createdBy;
|
||||||
|
this.budget = budget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
// This should only be set from Hibernate so it shouldn't actually be null ever
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Instant date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(Long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(Category category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getExpense() {
|
||||||
|
return expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpense(Boolean expense) {
|
||||||
|
this.expense = expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getCreatedBy() {
|
||||||
|
return createdBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Budget getBudget() {
|
||||||
|
return budget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBudget(Budget budget) {
|
||||||
|
this.budget = budget;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(RecurringTransaction other) {
|
||||||
|
return this.date.compareTo(other.date);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.wbrawner.twigs.recurringtransaction;
|
||||||
|
|
||||||
|
import com.wbrawner.twigs.budget.Budget;
|
||||||
|
import com.wbrawner.twigs.category.Category;
|
||||||
|
import com.wbrawner.twigs.transaction.Transaction;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface RecurringTransactionRepository extends CrudRepository<RecurringTransaction, String>,
|
||||||
|
PagingAndSortingRepository<RecurringTransaction, String> {
|
||||||
|
Optional<Transaction> findByIdAndBudgetIn(String id, List<Budget> budgets);
|
||||||
|
|
||||||
|
List<Transaction> findAllByBudgetInAndCategoryInAndDateGreaterThanAndDateLessThan(
|
||||||
|
List<Budget> budgets,
|
||||||
|
List<Category> categories,
|
||||||
|
Instant start,
|
||||||
|
Instant end,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Transaction> findAllByBudgetInAndDateGreaterThanAndDateLessThan(
|
||||||
|
List<Budget> budgets,
|
||||||
|
Instant start,
|
||||||
|
Instant end,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Transaction> findAllByBudgetAndCategory(Budget budget, Category category);
|
||||||
|
|
||||||
|
void deleteAllByBudget(Budget budget);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.wbrawner.twigs.passwordresetrequest;
|
package com.wbrawner.twigs.user;
|
||||||
|
|
||||||
import com.wbrawner.twigs.user.User;
|
import com.wbrawner.twigs.user.User;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.wbrawner.twigs.passwordresetrequest;
|
package com.wbrawner.twigs.user;
|
||||||
|
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
|
37
core/src/main/java/com/wbrawner/twigs/user/UserService.java
Normal file
37
core/src/main/java/com/wbrawner/twigs/user/UserService.java
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package com.wbrawner.twigs.user;
|
||||||
|
|
||||||
|
import com.wbrawner.twigs.session.Session;
|
||||||
|
import com.wbrawner.twigs.session.UserSessionRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static com.wbrawner.twigs.Utils.getCurrentUser;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
private final DaoAuthenticationProvider authenticationProvider;
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
private final UserSessionRepository userSessionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserService(DaoAuthenticationProvider authenticationProvider, UserRepository userRepository, UserSessionRepository userSessionRepository) {
|
||||||
|
this.authenticationProvider = authenticationProvider;
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.userSessionRepository = userSessionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session login(String username, String password) throws AuthenticationException {
|
||||||
|
var authReq = new UsernamePasswordAuthenticationToken(username, password);
|
||||||
|
Authentication auth = authenticationProvider.authenticate(authReq);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
|
var user = Objects.requireNonNull(getCurrentUser());
|
||||||
|
return userSessionRepository.save(new Session(user.getId()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,4 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rootProject.name = 'twigs'
|
rootProject.name = 'twigs'
|
||||||
include ':api'
|
include ':api'
|
||||||
|
include 'app'
|
||||||
|
include 'core'
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue