From a2558b02becef315ae5e7cce7b8c0768dedab0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Piotrkowski?= Date: Sun, 24 Aug 2025 15:06:40 +0200 Subject: [PATCH 1/5] feat(auth): add JWT token generation --- pom.xml | 22 +++++ .../org/pkwmtt/repository/UserRepository.java | 2 + .../pkwmtt/security/auth/AuthController.java | 24 ++++++ .../org/pkwmtt/security/auth/AuthService.java | 8 ++ .../pkwmtt/security/auth/AuthServiceImpl.java | 30 +++++++ .../security/auth/dto/UserRequestDTO.java | 9 +++ .../provider/OTPAuthenticationProvider.java | 69 ++++++++++++++++ .../security/config/SpringSecurity.java | 16 ++++ .../org/pkwmtt/security/token/JwtService.java | 9 +++ .../pkwmtt/security/token/JwtServiceImpl.java | 81 +++++++++++++++++++ .../pkwmtt/security/token/dto/UserDTO.java | 18 +++++ .../pkwmtt/security/token/utils/JwtUtils.java | 20 +++++ .../org/pkwmtt/jwt/JwtSecretMakerTest.java | 21 +++++ 13 files changed, 329 insertions(+) create mode 100644 src/main/java/org/pkwmtt/security/auth/AuthController.java create mode 100644 src/main/java/org/pkwmtt/security/auth/AuthService.java create mode 100644 src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java create mode 100644 src/main/java/org/pkwmtt/security/auth/dto/UserRequestDTO.java create mode 100644 src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java create mode 100644 src/main/java/org/pkwmtt/security/token/JwtService.java create mode 100644 src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java create mode 100644 src/main/java/org/pkwmtt/security/token/dto/UserDTO.java create mode 100644 src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java create mode 100644 src/test/java/org/pkwmtt/jwt/JwtSecretMakerTest.java diff --git a/pom.xml b/pom.xml index 1ab2d6a..91cc172 100644 --- a/pom.xml +++ b/pom.xml @@ -87,6 +87,25 @@ spring-security-test test + + io.jsonwebtoken + jjwt-api + 0.12.7 + + + io.jsonwebtoken + jjwt-impl + 0.12.7 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.12.7 + runtime + + + junit @@ -138,6 +157,7 @@ org.springframework.boot spring-boot-starter-actuator + ch.qos.logback @@ -149,11 +169,13 @@ wiremock-spring-boot 3.10.0 + org.springframework.boot spring-boot-starter-mail + io.github.cdimascio diff --git a/src/main/java/org/pkwmtt/repository/UserRepository.java b/src/main/java/org/pkwmtt/repository/UserRepository.java index 71ccd75..1e53f12 100644 --- a/src/main/java/org/pkwmtt/repository/UserRepository.java +++ b/src/main/java/org/pkwmtt/repository/UserRepository.java @@ -2,6 +2,8 @@ import org.pkwmtt.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; public interface UserRepository extends JpaRepository { + Optional findByEmail(String email); } \ No newline at end of file diff --git a/src/main/java/org/pkwmtt/security/auth/AuthController.java b/src/main/java/org/pkwmtt/security/auth/AuthController.java new file mode 100644 index 0000000..8855825 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/auth/AuthController.java @@ -0,0 +1,24 @@ +package org.pkwmtt.security.auth; + +import lombok.RequiredArgsConstructor; +import org.pkwmtt.security.auth.dto.UserRequestDTO; +import org.pkwmtt.security.token.JwtServiceImpl; +import org.pkwmtt.security.token.dto.UserDTO; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/pkwmtt/auth") +@RequiredArgsConstructor +public class AuthController { + private final AuthService authService; + private final JwtServiceImpl jwtServiceImpl; + + @PostMapping("/authenticate") + public String authenticate(@RequestBody UserRequestDTO requestUser) { + UserDTO user = authService.authenticateUser(requestUser); + return jwtServiceImpl.generateToken(user); + } +} diff --git a/src/main/java/org/pkwmtt/security/auth/AuthService.java b/src/main/java/org/pkwmtt/security/auth/AuthService.java new file mode 100644 index 0000000..7b60b77 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/auth/AuthService.java @@ -0,0 +1,8 @@ +package org.pkwmtt.security.auth; + +import org.pkwmtt.security.auth.dto.UserRequestDTO; +import org.pkwmtt.security.token.dto.UserDTO; + +public interface AuthService { + UserDTO authenticateUser(UserRequestDTO requestUser); +} diff --git a/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java b/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java new file mode 100644 index 0000000..382c83f --- /dev/null +++ b/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java @@ -0,0 +1,30 @@ +package org.pkwmtt.security.auth; + +import lombok.RequiredArgsConstructor; +import org.pkwmtt.security.auth.dto.UserRequestDTO; +import org.pkwmtt.security.token.dto.UserDTO; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AuthServiceImpl implements AuthService { + private final AuthenticationManager authenticationManager; + + @Override + public UserDTO authenticateUser(UserRequestDTO requestUser) { + Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken( + requestUser.getEmail(), + requestUser.getOtp_code() + )); + + if (!authentication.isAuthenticated()) { + throw new UsernameNotFoundException("Invalid credentials"); + } + + return (UserDTO) authentication.getPrincipal(); + } +} diff --git a/src/main/java/org/pkwmtt/security/auth/dto/UserRequestDTO.java b/src/main/java/org/pkwmtt/security/auth/dto/UserRequestDTO.java new file mode 100644 index 0000000..f30ed0e --- /dev/null +++ b/src/main/java/org/pkwmtt/security/auth/dto/UserRequestDTO.java @@ -0,0 +1,9 @@ +package org.pkwmtt.security.auth.dto; + +import lombok.Data; + +@Data +public class UserRequestDTO { + private String otp_code; + private String email; +} diff --git a/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java b/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java new file mode 100644 index 0000000..d2b6894 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java @@ -0,0 +1,69 @@ +package org.pkwmtt.security.auth.provider; +import lombok.RequiredArgsConstructor; +import org.pkwmtt.entity.User; +import org.pkwmtt.repository.UserRepository; +import org.pkwmtt.security.token.dto.UserDTO; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Stream; + +@Component +@RequiredArgsConstructor +public class OTPAuthenticationProvider implements AuthenticationProvider { + private final UserRepository userRepository; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String email = authentication.getName(); + String otpCode = authentication.getCredentials().toString(); + + // Fetch user from DB + User user = userRepository.findByEmail(email) + .orElseThrow(() -> new BadCredentialsException("User not found")); + + // Wrap role in a list to support multiple roles in the future + List authorities = Stream.of(user.getRole()) + .map(role -> new SimpleGrantedAuthority("ROLE_" + role.name())) + .toList(); + + // Validate critical user fields before OTP check + if(!isValidForAuthentication(user)){ + throw new BadCredentialsException( + "Invalid User Credentials. Please contact the administrator." + ); + } + + // TODO: integrate with real OTP service + boolean OTP_SERVICE_AUTH_RESULT = true; + + if(OTP_SERVICE_AUTH_RESULT){ + UserDTO userMapped = new UserDTO(user); + return new UsernamePasswordAuthenticationToken(userMapped, otpCode, authorities); + } else { + throw new BadCredentialsException("Invalid OTP"); + } + } + + @Override + public boolean supports(Class authentication) { + return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); + } + + /** + * Validates user data before authentication. + * Returns true if user has email, role, group, and is active. + */ + private boolean isValidForAuthentication(User user) { + return user.getEmail() != null && + user.getRole() != null && + user.getGeneralGroup() != null && + user.isActive(); + } +} diff --git a/src/main/java/org/pkwmtt/security/config/SpringSecurity.java b/src/main/java/org/pkwmtt/security/config/SpringSecurity.java index c4dc591..7cf7a82 100644 --- a/src/main/java/org/pkwmtt/security/config/SpringSecurity.java +++ b/src/main/java/org/pkwmtt/security/config/SpringSecurity.java @@ -1,21 +1,32 @@ package org.pkwmtt.security.config; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.pkwmtt.security.auth.provider.OTPAuthenticationProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; +import java.util.List; + import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; //@EnableWebSecurity @Slf4j @Configuration +@RequiredArgsConstructor public class SpringSecurity { + private final OTPAuthenticationProvider otpAuthenticationProvider; + @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { log.info("Configuring Security Filter Chain..."); @@ -30,4 +41,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { log.info("Configuring Success..."); return http.build(); } + + @Bean + public AuthenticationManager authenticationManager() { + return new ProviderManager(List.of(otpAuthenticationProvider)); + } } diff --git a/src/main/java/org/pkwmtt/security/token/JwtService.java b/src/main/java/org/pkwmtt/security/token/JwtService.java new file mode 100644 index 0000000..e248f86 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/token/JwtService.java @@ -0,0 +1,9 @@ +package org.pkwmtt.security.token; + +import org.pkwmtt.security.token.dto.UserDTO; + +public interface JwtService { + String generateToken(UserDTO user); + Boolean validateToken(String token); + String getUserIdFromToken(String token); +} diff --git a/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java b/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java new file mode 100644 index 0000000..7453328 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java @@ -0,0 +1,81 @@ +package org.pkwmtt.security.token; + +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import lombok.RequiredArgsConstructor; +import org.pkwmtt.security.token.dto.UserDTO; +import org.pkwmtt.security.token.utils.JwtUtils; +import org.springframework.stereotype.Service; + +import javax.crypto.SecretKey; +import java.util.Base64; +import java.util.Date; + +@Service +@RequiredArgsConstructor +public class JwtServiceImpl implements JwtService { + private final JwtUtils jwtUtils; + + + /** + * Generates a JWT token for a given user. + * The token contains user's email, group, and role as claims, + * and is signed with a secret key. + * + * @param user - required user data to include in token claims + * @return signed JWT token as a String + */ + @Override + public String generateToken(UserDTO user) { + return Jwts.builder() + .subject(user.getEmail()) + .claim("group", user.getGroup()) + .claim("role", user.getRole()) + .issuedAt(new Date()) + .expiration((new Date(System.currentTimeMillis() + jwtUtils.getEXPIRATION_MS()))) + .signWith(decodeSecretKey()) + .compact(); + } + + + /** + * Decode a secret key for signing JWT. + * The key is decoded from Base64 stored in JwtUtils configuration. + * + * @return secret key for JWT signing + */ + private SecretKey decodeSecretKey(){ + byte[] decodedKey = Base64.getDecoder().decode(jwtUtils.getSECRET()); + return Keys.hmacShaKeyFor(decodedKey); + } + + /** + * Validate a JWT token. + * Attempts to parse the token; if parsing fails, the token is considered invalid. + * + * @param token JWT token string to validate + * @return true if the token is valid, false otherwise + */ + @Override + public Boolean validateToken(String token) { + try { + // TODO: add logic to validate the token + return true; + } catch (JwtException | IllegalArgumentException e) { + return false; + } + } + + /** + * Extracts the user identifier (email) from a JWT token. + * + * @param token JWT token to extract user from + * @return user email from token + */ + @Override + public String getUserIdFromToken(String token) { + // TODO: implement token parsing to extract subject/email + return ""; + } +} diff --git a/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java b/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java new file mode 100644 index 0000000..8736f61 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java @@ -0,0 +1,18 @@ +package org.pkwmtt.security.token.dto; + +import lombok.Data; +import org.pkwmtt.entity.User; +import org.pkwmtt.enums.Role; + +@Data +public class UserDTO { + private String email; + private String group; + private Role role; + + public UserDTO(User user){ + this.email = user.getEmail(); + this.group = user.getGeneralGroup() != null ? user.getGeneralGroup().getName() : null; + this.role = user.getRole(); + } +} diff --git a/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java new file mode 100644 index 0000000..a9d18a7 --- /dev/null +++ b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java @@ -0,0 +1,20 @@ +package org.pkwmtt.security.token.utils; + +import lombok.Getter; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Getter +@Component +public class JwtUtils { + private Environment environment; + private final String SECRET; + private final long EXPIRATION_MS = 1000L * 60 * 60 * 24 * 30 * 6; + + public JwtUtils(Environment environment) { + this.SECRET = environment.getProperty("JWT_SECRET_KEY"); + if(this.SECRET == null) { + throw new RuntimeException("JWT_SECRET_KEY not found in environment variables"); + } + } +} diff --git a/src/test/java/org/pkwmtt/jwt/JwtSecretMakerTest.java b/src/test/java/org/pkwmtt/jwt/JwtSecretMakerTest.java new file mode 100644 index 0000000..ed43d5d --- /dev/null +++ b/src/test/java/org/pkwmtt/jwt/JwtSecretMakerTest.java @@ -0,0 +1,21 @@ +package org.pkwmtt.jwt; + +import io.jsonwebtoken.Jwts; +import jakarta.xml.bind.DatatypeConverter; +import org.junit.jupiter.api.Test; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class JwtSecretMakerTest { + + @Test + public void generateSecretKey(){ + SecretKey key = Jwts.SIG.HS512.key().build(); + String encodedKey = DatatypeConverter.printHexBinary(key.getEncoded()); + System.out.printf("\nKey = [%s]\n", encodedKey); + String base64Secret = Base64.getEncoder().encodeToString(encodedKey.getBytes(StandardCharsets.UTF_8)); + System.out.println(base64Secret); + } +} From 2cd2aa3aa3a13a0391f7a62b70276ea08b86c084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Piotrkowski?= Date: Sun, 24 Aug 2025 15:12:12 +0200 Subject: [PATCH 2/5] fix: remove unused imports and improve JwtUtils class --- .../org/pkwmtt/security/config/SpringSecurity.java | 3 --- .../org/pkwmtt/security/token/utils/JwtUtils.java | 11 +++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/pkwmtt/security/config/SpringSecurity.java b/src/main/java/org/pkwmtt/security/config/SpringSecurity.java index 7cf7a82..37aea49 100644 --- a/src/main/java/org/pkwmtt/security/config/SpringSecurity.java +++ b/src/main/java/org/pkwmtt/security/config/SpringSecurity.java @@ -6,11 +6,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; diff --git a/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java index a9d18a7..0d07a92 100644 --- a/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java +++ b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java @@ -7,14 +7,13 @@ @Getter @Component public class JwtUtils { - private Environment environment; - private final String SECRET; - private final long EXPIRATION_MS = 1000L * 60 * 60 * 24 * 30 * 6; + private final String secret; + private final long expirationMs = 1000L * 60 * 60 * 24 * 30 * 6; public JwtUtils(Environment environment) { - this.SECRET = environment.getProperty("JWT_SECRET_KEY"); - if(this.SECRET == null) { - throw new RuntimeException("JWT_SECRET_KEY not found in environment variables"); + this.secret = environment.getProperty("JWT_SECRET_KEY"); + if(this.secret == null) { + throw new IllegalStateException("JWT_SECRET_KEY not found in environment variables"); } } } From 84bddb004b0a268251cbfb31eb4841140b8d34c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Piotrkowski?= Date: Sun, 24 Aug 2025 15:13:21 +0200 Subject: [PATCH 3/5] fix: fields names --- src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java b/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java index 7453328..f94079e 100644 --- a/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java +++ b/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java @@ -33,7 +33,7 @@ public String generateToken(UserDTO user) { .claim("group", user.getGroup()) .claim("role", user.getRole()) .issuedAt(new Date()) - .expiration((new Date(System.currentTimeMillis() + jwtUtils.getEXPIRATION_MS()))) + .expiration((new Date(System.currentTimeMillis() + jwtUtils.getExpirationMs()))) .signWith(decodeSecretKey()) .compact(); } @@ -46,7 +46,7 @@ public String generateToken(UserDTO user) { * @return secret key for JWT signing */ private SecretKey decodeSecretKey(){ - byte[] decodedKey = Base64.getDecoder().decode(jwtUtils.getSECRET()); + byte[] decodedKey = Base64.getDecoder().decode(jwtUtils.getSecret()); return Keys.hmacShaKeyFor(decodedKey); } From 0702118c6488f13c624a89d60abab5bd91b8c6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Piotrkowski?= Date: Sun, 24 Aug 2025 15:29:10 +0200 Subject: [PATCH 4/5] Fallback to default JWT secret if env var missing --- .../java/org/pkwmtt/security/token/utils/JwtUtils.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java index 0d07a92..21ee1bb 100644 --- a/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java +++ b/src/main/java/org/pkwmtt/security/token/utils/JwtUtils.java @@ -7,13 +7,14 @@ @Getter @Component public class JwtUtils { + // Secret key used for signing JWTs. If the environment variable JWT_SECRET_KEY + // is not set, a default value "TEST_SECRET" is used. This allows the application + // to start without a real secret, e.g., for local development or tests. private final String secret; private final long expirationMs = 1000L * 60 * 60 * 24 * 30 * 6; public JwtUtils(Environment environment) { - this.secret = environment.getProperty("JWT_SECRET_KEY"); - if(this.secret == null) { - throw new IllegalStateException("JWT_SECRET_KEY not found in environment variables"); - } + // Get the secret key from environment variables, or fallback to "TEST_SECRET" + this.secret = environment.getProperty("JWT_SECRET_KEY", "TEST_SECRET"); } } From e8b503446fe4ebbcde2bc9c4ddf13b9b46d78110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Piotrkowski?= Date: Fri, 29 Aug 2025 07:04:50 +0200 Subject: [PATCH 5/5] feat(auth): update authentication args and improve UserDTO initialization - Refactored user authentication function arguments for clarity - Initialized UserDTO using Optional to handle nullable values - Removed redundant null-checking logic and unnecessary code --- .../org/pkwmtt/security/auth/AuthController.java | 2 +- .../java/org/pkwmtt/security/auth/AuthService.java | 3 +-- .../org/pkwmtt/security/auth/AuthServiceImpl.java | 6 +++--- .../auth/provider/OTPAuthenticationProvider.java | 14 +++----------- .../org/pkwmtt/security/token/dto/UserDTO.java | 7 ++++++- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/pkwmtt/security/auth/AuthController.java b/src/main/java/org/pkwmtt/security/auth/AuthController.java index 8855825..f86dd7a 100644 --- a/src/main/java/org/pkwmtt/security/auth/AuthController.java +++ b/src/main/java/org/pkwmtt/security/auth/AuthController.java @@ -18,7 +18,7 @@ public class AuthController { @PostMapping("/authenticate") public String authenticate(@RequestBody UserRequestDTO requestUser) { - UserDTO user = authService.authenticateUser(requestUser); + UserDTO user = authService.authenticateUser(requestUser.getEmail()); return jwtServiceImpl.generateToken(user); } } diff --git a/src/main/java/org/pkwmtt/security/auth/AuthService.java b/src/main/java/org/pkwmtt/security/auth/AuthService.java index 7b60b77..3fc3cde 100644 --- a/src/main/java/org/pkwmtt/security/auth/AuthService.java +++ b/src/main/java/org/pkwmtt/security/auth/AuthService.java @@ -1,8 +1,7 @@ package org.pkwmtt.security.auth; -import org.pkwmtt.security.auth.dto.UserRequestDTO; import org.pkwmtt.security.token.dto.UserDTO; public interface AuthService { - UserDTO authenticateUser(UserRequestDTO requestUser); + UserDTO authenticateUser(String email); } diff --git a/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java b/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java index 382c83f..a878b52 100644 --- a/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java +++ b/src/main/java/org/pkwmtt/security/auth/AuthServiceImpl.java @@ -15,10 +15,10 @@ public class AuthServiceImpl implements AuthService { private final AuthenticationManager authenticationManager; @Override - public UserDTO authenticateUser(UserRequestDTO requestUser) { + public UserDTO authenticateUser(String email) { Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken( - requestUser.getEmail(), - requestUser.getOtp_code() + email, + null )); if (!authentication.isAuthenticated()) { diff --git a/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java b/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java index d2b6894..4baf894 100644 --- a/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java +++ b/src/main/java/org/pkwmtt/security/auth/provider/OTPAuthenticationProvider.java @@ -22,7 +22,6 @@ public class OTPAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String email = authentication.getName(); - String otpCode = authentication.getCredentials().toString(); // Fetch user from DB User user = userRepository.findByEmail(email) @@ -33,22 +32,15 @@ public Authentication authenticate(Authentication authentication) throws Authent .map(role -> new SimpleGrantedAuthority("ROLE_" + role.name())) .toList(); - // Validate critical user fields before OTP check + // Validate critical user fields if(!isValidForAuthentication(user)){ throw new BadCredentialsException( "Invalid User Credentials. Please contact the administrator." ); } - // TODO: integrate with real OTP service - boolean OTP_SERVICE_AUTH_RESULT = true; - - if(OTP_SERVICE_AUTH_RESULT){ - UserDTO userMapped = new UserDTO(user); - return new UsernamePasswordAuthenticationToken(userMapped, otpCode, authorities); - } else { - throw new BadCredentialsException("Invalid OTP"); - } + UserDTO userMapped = new UserDTO(user); + return new UsernamePasswordAuthenticationToken(userMapped, null, authorities); } @Override diff --git a/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java b/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java index 8736f61..b193edd 100644 --- a/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java +++ b/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java @@ -1,9 +1,12 @@ package org.pkwmtt.security.token.dto; import lombok.Data; +import org.pkwmtt.entity.GeneralGroup; import org.pkwmtt.entity.User; import org.pkwmtt.enums.Role; +import java.util.Optional; + @Data public class UserDTO { private String email; @@ -12,7 +15,9 @@ public class UserDTO { public UserDTO(User user){ this.email = user.getEmail(); - this.group = user.getGeneralGroup() != null ? user.getGeneralGroup().getName() : null; this.role = user.getRole(); + this.group = Optional.ofNullable(user.getGeneralGroup()) + .map(GeneralGroup::getName) + .orElse(null); } }