-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pieter Van Eeckhout
committed
Jun 25, 2023
1 parent
1ccc2c1
commit 7e97e55
Showing
23 changed files
with
512 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
...src/main/java/io/edpn/backend/application/controller/BootJwtAuthenticationController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package io.edpn.backend.application.controller; | ||
|
||
import io.edpn.backend.user.application.controller.DefaultJwtAuthenticationController; | ||
import io.edpn.backend.user.domain.service.JwtTokenService; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
public class BootJwtAuthenticationController extends DefaultJwtAuthenticationController { | ||
|
||
public BootJwtAuthenticationController(PasswordEncoder passwordEncoder, UserDetailsService userDetailsService, JwtTokenService jwtTokenUtil) { | ||
super(passwordEncoder, userDetailsService, jwtTokenUtil); | ||
} | ||
} |
18 changes: 6 additions & 12 deletions
18
boot/src/main/java/io/edpn/backend/application/controller/BootTradeModuleController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,16 @@ | ||
package io.edpn.backend.application.controller; | ||
|
||
import io.edpn.backend.trade.application.controller.DefaultTradeModuleController; | ||
import io.edpn.backend.trade.domain.service.BestCommodityPriceService; | ||
import io.edpn.backend.trade.application.controller.TradeModuleController; | ||
import io.edpn.backend.trade.application.dto.CommodityMarketInfoResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import java.util.List; | ||
|
||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class BootTradeModuleController implements TradeModuleController { | ||
|
||
private final BestCommodityPriceService bestCommodityPriceService; | ||
public class BootTradeModuleController extends DefaultTradeModuleController { | ||
|
||
@Override | ||
public List<CommodityMarketInfoResponse> getBestCommodityPrice() { | ||
return bestCommodityPriceService.getCommodityMarketInfo(); | ||
@Autowired | ||
public BootTradeModuleController(BestCommodityPriceService bestCommodityPriceService) { | ||
super(bestCommodityPriceService); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,15 @@ | ||
module edpn.boot { | ||
module io.edpn.backend.boot { | ||
requires static lombok; | ||
requires spring.boot; | ||
requires org.mybatis.spring; | ||
requires spring.boot.autoconfigure; | ||
requires spring.context; | ||
requires io.edpn.backend.trade; | ||
requires spring.web; | ||
requires spring.beans; | ||
requires spring.boot.starter.security; | ||
|
||
requires io.edpn.backend.trade; | ||
requires io.edpn.backend.user; | ||
|
||
opens io.edpn.backend.application.controller to spring.core; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ rootProject.name = 'backend' | |
// modules | ||
include 'boot' | ||
include 'trade-module' | ||
include 'user-module' |
19 changes: 19 additions & 0 deletions
19
.../main/java/io/edpn/backend/trade/application/controller/DefaultTradeModuleController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.edpn.backend.trade.application.controller; | ||
|
||
import io.edpn.backend.trade.application.dto.CommodityMarketInfoResponse; | ||
import io.edpn.backend.trade.domain.controller.TradeModuleController; | ||
import io.edpn.backend.trade.domain.service.BestCommodityPriceService; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
|
||
@RequiredArgsConstructor | ||
public class DefaultTradeModuleController implements TradeModuleController { | ||
|
||
private final BestCommodityPriceService bestCommodityPriceService; | ||
|
||
@Override | ||
public List<CommodityMarketInfoResponse> getBestCommodityPrice() { | ||
return bestCommodityPriceService.getCommodityMarketInfo(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...ion/controller/TradeModuleController.java → ...ain/controller/TradeModuleController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
dependencies { | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation 'org.springframework.boot:spring-boot-starter-jdbc' | ||
implementation 'org.springframework.boot:spring-boot-starter-security' | ||
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter' | ||
implementation 'org.liquibase:liquibase-core' | ||
implementation 'io.jsonwebtoken:jjwt' | ||
implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core' | ||
|
||
compileOnly 'jakarta.servlet:jakarta.servlet-api' | ||
compileOnly 'org.projectlombok:lombok' | ||
|
||
annotationProcessor 'org.projectlombok:lombok' | ||
|
||
testCompileOnly 'org.projectlombok:lombok' | ||
testAnnotationProcessor 'org.projectlombok:lombok' | ||
} | ||
|
||
extraJavaModuleInfo { | ||
automaticModule("dependency-management-plugin-1.1.0.jar","dependency.management.plugin") | ||
//automaticModule("tomlj-1.0.0.jar","tomlj") | ||
automaticModule("jsr305-3.0.2.jar","jsr305") | ||
automaticModule("snappy-java-1.1.8.4.jar","snappy.java") | ||
automaticModule("liquibase-core-4.17.2.jar","liquibase.core") | ||
automaticModule("jjwt-0.9.1.jar", "io.jsonwebtoken") | ||
/* | ||
automaticModule("jersey-media-json-jackson-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-container-servlet-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-spring6-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-container-servlet-core-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-bean-validation-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-server-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-client-3.1.1.jar", "jersy.jackson") | ||
automaticModule("jersey-hk2-3.1.1.jar", "jersy.jackson") | ||
automaticModule("hk2-3.0.3.jar", "jersy.jackson") | ||
automaticModule("jersey-entity-filtering-3.1.1.jar", "jersy.jackson") | ||
automaticModule("osgi-resource-locator-1.0.3.jar", "jersy.jackson") | ||
automaticModule("javassist-3.29.0-GA.jar", "jersy.jackson") | ||
automaticModule("jersey-common-3.1.1.jar", "jersy.jackson")*/ | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
.../java/io/edpn/backend/user/application/controller/DefaultJwtAuthenticationController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package io.edpn.backend.user.application.controller; | ||
|
||
|
||
import io.edpn.backend.user.domain.controller.AuthenticationController; | ||
import io.edpn.backend.user.domain.service.JwtTokenService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.authentication.BadCredentialsException; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
|
||
@RequiredArgsConstructor | ||
public class DefaultJwtAuthenticationController implements AuthenticationController { | ||
|
||
private final PasswordEncoder passwordEncoder; | ||
private final UserDetailsService userDetailsService; | ||
private final JwtTokenService jwtTokenUtil; | ||
|
||
@Override | ||
public ResponseEntity<? extends AuthenticationResponse> createAuthenticationToken(AuthenticationRequest jsonAuthenticationRequest) throws BadCredentialsException { | ||
try { | ||
final UserDetails userDetails = userDetailsService | ||
.loadUserByUsername(jsonAuthenticationRequest.getUsername()); | ||
if (passwordEncoder.matches(jsonAuthenticationRequest.getPassword(), userDetails.getPassword())) { | ||
throw new BadCredentialsException("Incorrect username or password"); | ||
} | ||
|
||
var response = io.edpn.backend.user.application.dto.AuthenticationResponse.builder() | ||
.jwt(jwtTokenUtil.generateToken(userDetails)) | ||
.refreshToken(jwtTokenUtil.generateRefreshToken(userDetails)) | ||
.build(); | ||
|
||
return ResponseEntity.ok(response); | ||
} catch (UsernameNotFoundException unfe) { | ||
throw new BadCredentialsException("Incorrect username or password", unfe); | ||
} | ||
} | ||
|
||
@Override | ||
public ResponseEntity<? extends AuthenticationResponse> refreshToken(RefreshTokenRequest refreshTokenRequest) throws Exception { | ||
String refreshToken = refreshTokenRequest.getRefreshToken(); | ||
String username = jwtTokenUtil.extractUsername(refreshToken); | ||
|
||
final UserDetails userDetails = userDetailsService.loadUserByUsername(username); | ||
|
||
if (jwtTokenUtil.validateToken(refreshToken, userDetails)) { | ||
var response = io.edpn.backend.user.application.dto.AuthenticationResponse.builder() | ||
.jwt(jwtTokenUtil.generateToken(userDetails)) | ||
.refreshToken(refreshToken) // do not send a new refresh token, need to log in again after 24 hours | ||
.build(); | ||
|
||
return ResponseEntity.ok(response); | ||
} else { | ||
throw new Exception("Invalid refresh token"); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
user-module/src/main/java/io/edpn/backend/user/application/dto/AuthenticationResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package io.edpn.backend.user.application.dto; | ||
|
||
import io.edpn.backend.user.domain.controller.AuthenticationController; | ||
import lombok.Builder; | ||
import lombok.Value; | ||
|
||
@Value(staticConstructor = "of") | ||
@Builder | ||
public class AuthenticationResponse implements AuthenticationController.AuthenticationResponse { | ||
String jwt; | ||
String refreshToken; | ||
} |
81 changes: 81 additions & 0 deletions
81
...module/src/main/java/io/edpn/backend/user/application/service/DefaultJwtTokenService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package io.edpn.backend.user.application.service; | ||
|
||
import io.edpn.backend.user.domain.service.JwtTokenService; | ||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.SignatureAlgorithm; | ||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class DefaultJwtTokenService implements JwtTokenService { | ||
|
||
@Value("${jwt.secret:secret}") | ||
private String secret; | ||
|
||
@Override | ||
public String extractUsername(String token) { | ||
return extractClaim(token, Claims::getSubject); | ||
} | ||
|
||
@Override | ||
public Date extractExpiration(String token) { | ||
return extractClaim(token, Claims::getExpiration); | ||
} | ||
|
||
@Override | ||
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) { | ||
final Claims claims = extractAllClaims(token); | ||
return claimsResolver.apply(claims); | ||
} | ||
|
||
@Override | ||
public Claims extractAllClaims(String token) { | ||
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); | ||
} | ||
|
||
@Override | ||
public Boolean isTokenExpired(String token) { | ||
return extractExpiration(token).before(new Date()); | ||
} | ||
|
||
@Override | ||
public String generateToken(UserDetails userDetails) { | ||
Map<String, Object> claims = new HashMap<>(); | ||
return createToken(claims, userDetails.getUsername()); | ||
} | ||
|
||
@Override | ||
public String createToken(Map<String, Object> claims, String subject) { | ||
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())) | ||
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 1)) // 1 hours token validity | ||
.signWith(SignatureAlgorithm.HS512, secret).compact(); | ||
} | ||
|
||
@Override | ||
public Boolean validateToken(String token, UserDetails userDetails) { | ||
final String username = extractUsername(token); | ||
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); | ||
} | ||
|
||
@Override | ||
public String generateRefreshToken(UserDetails userDetails) { | ||
Map<String, Object> claims = new HashMap<>(); | ||
return createRefreshToken(claims, userDetails.getUsername()); | ||
} | ||
|
||
@Override | ||
public String createRefreshToken(Map<String, Object> claims, String subject) { | ||
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())) | ||
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)) // 24 hours token validity | ||
.signWith(SignatureAlgorithm.HS512, secret).compact(); | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
user-module/src/main/java/io/edpn/backend/user/configuration/SecurityConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package io.edpn.backend.user.configuration; | ||
|
||
import io.edpn.backend.user.configuration.filter.JwtRequestFilter; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
import static org.springframework.security.config.Customizer.withDefaults; | ||
|
||
@Configuration | ||
public class SecurityConfiguration { | ||
|
||
@Bean | ||
public SecurityFilterChain endpointSecurityFilterChain(HttpSecurity http) throws Exception { | ||
http | ||
.authorizeHttpRequests((authz) -> authz | ||
.anyRequest().authenticated() | ||
) | ||
.httpBasic(withDefaults()); | ||
return http.build(); | ||
} | ||
|
||
@Bean | ||
public SecurityFilterChain jwtRequestFilterFilterChain(HttpSecurity http, JwtRequestFilter jwtRequestFilter) throws Exception { | ||
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); | ||
return http.build(); | ||
} | ||
|
||
|
||
@Bean | ||
public PasswordEncoder getPasswordEncoder() { | ||
return new BCryptPasswordEncoder(); | ||
} | ||
} |
Oops, something went wrong.