style: clean up whitespace in multiple files
Some checks failed
CI / Get Changed Files (pull_request) Successful in 8s
CI / Docker frontend validation (pull_request) Successful in 24s
CI / eslint (pull_request) Successful in 30s
CI / oxlint (pull_request) Successful in 39s
CI / prettier (pull_request) Failing after 43s
CI / Checkstyle Main (pull_request) Failing after 1m22s
CI / test-build (pull_request) Successful in 1m44s
CI / Docker backend validation (pull_request) Failing after 1m54s

This commit is contained in:
Constantin Simonis 2025-05-21 10:33:58 +02:00
commit 74798949c6
No known key found for this signature in database
GPG key ID: 3878FF77C24AF4D2
27 changed files with 119 additions and 149 deletions

View file

@ -8,9 +8,6 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;

View file

@ -112,7 +112,6 @@ public class BlackJackService {
dealCardToPlayer(game); dealCardToPlayer(game);
dealCardToSplitHand(game); dealCardToSplitHand(game);
return blackJackGameRepository.save(game);
} }
private BlackJackGameEntity processGameBasedOnState(BlackJackGameEntity game) { private BlackJackGameEntity processGameBasedOnState(BlackJackGameEntity game) {

View file

@ -1,7 +1,6 @@
package de.szut.casino.config; package de.szut.casino.config;
import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.Info;

View file

@ -18,12 +18,12 @@ public class WebConfig {
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") registry.addMapping("/**")
.allowedOrigins(frontendHost) .allowedOrigins(frontendHost)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*") .allowedHeaders("*")
.exposedHeaders("*") .exposedHeaders("*")
.allowCredentials(true) .allowCredentials(true)
.maxAge(3600); .maxAge(3600);
} }
}; };
} }

View file

@ -53,8 +53,8 @@ public class DepositController {
.build()) .build())
.setQuantity(1L) .setQuantity(1L)
.build()) .build())
.setSuccessUrl(frontendHost+"/home?success=true") .setSuccessUrl(frontendHost + "/home?success=true")
.setCancelUrl(frontendHost+"/home?success=false") .setCancelUrl(frontendHost + "/home?success=false")
.setMode(SessionCreateParams.Mode.PAYMENT) .setMode(SessionCreateParams.Mode.PAYMENT)
.build(); .build();

View file

@ -1,7 +1,5 @@
package de.szut.casino.exceptionHandling.exceptions; package de.szut.casino.exceptionHandling.exceptions;
import de.szut.casino.security.service.EmailService;
public class EmailNotVerifiedException extends Exception { public class EmailNotVerifiedException extends Exception {
public EmailNotVerifiedException() { public EmailNotVerifiedException() {
super("Email not verified"); super("Email not verified");

View file

@ -1,9 +1,7 @@
package de.szut.casino.security; package de.szut.casino.security;
import de.szut.casino.exceptionHandling.ErrorDetails;
import de.szut.casino.exceptionHandling.exceptions.EmailNotVerifiedException; import de.szut.casino.exceptionHandling.exceptions.EmailNotVerifiedException;
import de.szut.casino.security.dto.AuthResponseDto; import de.szut.casino.security.dto.AuthResponseDto;
import de.szut.casino.security.dto.GithubCallbackDto;
import de.szut.casino.security.dto.LoginRequestDto; import de.szut.casino.security.dto.LoginRequestDto;
import de.szut.casino.security.dto.ResetPasswordDto; import de.szut.casino.security.dto.ResetPasswordDto;
import de.szut.casino.security.service.AuthService; import de.szut.casino.security.service.AuthService;
@ -24,7 +22,7 @@ public class AuthController {
@Autowired @Autowired
private AuthService authService; private AuthService authService;
@Autowired @Autowired
private GitHubService githubService; private GitHubService githubService;
@ -42,11 +40,11 @@ public class AuthController {
@PostMapping("/verify") @PostMapping("/verify")
public ResponseEntity<Void> verifyEmail(@RequestParam("token") String token) throws MessagingException, IOException { public ResponseEntity<Void> verifyEmail(@RequestParam("token") String token) throws MessagingException, IOException {
if (authService.verifyEmail(token)) { if (authService.verifyEmail(token)) {
return ResponseEntity.badRequest().build(); return ResponseEntity.badRequest().build();
} }
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@PostMapping("/recover-password") @PostMapping("/recover-password")

View file

@ -19,10 +19,10 @@ public class CorsFilter implements Filter {
@Override @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res; HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req; HttpServletRequest request = (HttpServletRequest) req;
// Allow requests from the frontend // Allow requests from the frontend
response.setHeader("Access-Control-Allow-Origin", frontendHost); response.setHeader("Access-Control-Allow-Origin", frontendHost);
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
@ -30,12 +30,12 @@ public class CorsFilter implements Filter {
response.setHeader("Access-Control-Expose-Headers", "*"); response.setHeader("Access-Control-Expose-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Max-Age", "3600");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
return; return;
} }
chain.doFilter(req, res); chain.doFilter(req, res);
} }
} }

View file

@ -7,7 +7,7 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> { public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
@Override @Override
public AbstractAuthenticationToken convert(Jwt source) { public AbstractAuthenticationToken convert(Jwt source) {
JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter(); JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();

View file

@ -2,26 +2,14 @@ package de.szut.casino.security;
import de.szut.casino.security.dto.AuthResponseDto; import de.szut.casino.security.dto.AuthResponseDto;
import de.szut.casino.security.dto.GithubCallbackDto; import de.szut.casino.security.dto.GithubCallbackDto;
import de.szut.casino.security.jwt.JwtUtils;
import de.szut.casino.user.AuthProvider;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserRepository;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.servlet.view.RedirectView;
import java.math.BigDecimal;
import java.util.*;
@RestController @RestController
@RequestMapping("/oauth2/github") @RequestMapping("/oauth2/github")
public class GitHubController { public class GitHubController {
@ -42,12 +30,12 @@ public class GitHubController {
@GetMapping("/authorize") @GetMapping("/authorize")
public RedirectView authorizeGithub() { public RedirectView authorizeGithub() {
logger.info("Redirecting to GitHub for authorization"); logger.info("Redirecting to GitHub for authorization");
String authUrl = authorizationUri + String authUrl = authorizationUri +
"?client_id=" + clientId + "?client_id=" + clientId +
"&redirect_uri=" + redirectUri + "&redirect_uri=" + redirectUri +
"&scope=user:email,read:user"; "&scope=user:email,read:user";
return new RedirectView(authUrl); return new RedirectView(authUrl);
} }

View file

@ -16,7 +16,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@ -50,19 +49,19 @@ public class GitHubService {
try { try {
// Exchange code for access token // Exchange code for access token
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
// Create request body for token endpoint // Create request body for token endpoint
Map<String, String> requestBody = new HashMap<>(); Map<String, String> requestBody = new HashMap<>();
requestBody.put("client_id", clientId); requestBody.put("client_id", clientId);
requestBody.put("client_secret", clientSecret); requestBody.put("client_secret", clientSecret);
requestBody.put("code", code); requestBody.put("code", code);
// Set headers // Set headers
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json"); headers.set("Accept", "application/json");
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers); HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
// Get access token // Get access token
ResponseEntity<Map> response = restTemplate.exchange( ResponseEntity<Map> response = restTemplate.exchange(
"https://github.com/login/oauth/access_token", "https://github.com/login/oauth/access_token",
@ -70,10 +69,10 @@ public class GitHubService {
requestEntity, requestEntity,
Map.class Map.class
); );
Map<String, Object> responseBody = response.getBody(); Map<String, Object> responseBody = response.getBody();
logger.info("GitHub token response: {}", responseBody); logger.info("GitHub token response: {}", responseBody);
// Check if there's an error in the response // Check if there's an error in the response
if (responseBody.containsKey("error")) { if (responseBody.containsKey("error")) {
String error = (String) responseBody.get("error"); String error = (String) responseBody.get("error");
@ -81,49 +80,49 @@ public class GitHubService {
logger.error("GitHub OAuth error: {} - {}", error, errorDescription); logger.error("GitHub OAuth error: {} - {}", error, errorDescription);
throw new RuntimeException("GitHub OAuth error: " + errorDescription); throw new RuntimeException("GitHub OAuth error: " + errorDescription);
} }
String accessToken = (String) responseBody.get("access_token"); String accessToken = (String) responseBody.get("access_token");
if (accessToken == null || accessToken.isEmpty()) { if (accessToken == null || accessToken.isEmpty()) {
logger.error("No access token received from GitHub"); logger.error("No access token received from GitHub");
throw new RuntimeException("Failed to receive access token from GitHub"); throw new RuntimeException("Failed to receive access token from GitHub");
} }
logger.info("Received access token from GitHub"); logger.info("Received access token from GitHub");
// Get user info // Get user info
HttpHeaders userInfoHeaders = new HttpHeaders(); HttpHeaders userInfoHeaders = new HttpHeaders();
userInfoHeaders.set("Authorization", "Bearer " + accessToken); userInfoHeaders.set("Authorization", "Bearer " + accessToken);
HttpEntity<String> userInfoRequestEntity = new HttpEntity<>(null, userInfoHeaders); HttpEntity<String> userInfoRequestEntity = new HttpEntity<>(null, userInfoHeaders);
logger.info("Making request to GitHub API with token: {}", accessToken.substring(0, 5) + "..."); logger.info("Making request to GitHub API with token: {}", accessToken.substring(0, 5) + "...");
ResponseEntity<Map> userResponse = restTemplate.exchange( ResponseEntity<Map> userResponse = restTemplate.exchange(
"https://api.github.com/user", "https://api.github.com/user",
HttpMethod.GET, HttpMethod.GET,
userInfoRequestEntity, userInfoRequestEntity,
Map.class Map.class
); );
Map<String, Object> userAttributes = userResponse.getBody(); Map<String, Object> userAttributes = userResponse.getBody();
logger.info("Retrieved user info from GitHub: {}", userAttributes.get("login")); logger.info("Retrieved user info from GitHub: {}", userAttributes.get("login"));
// Get user emails // Get user emails
HttpHeaders emailsHeaders = new HttpHeaders(); HttpHeaders emailsHeaders = new HttpHeaders();
emailsHeaders.set("Authorization", "Bearer " + accessToken); emailsHeaders.set("Authorization", "Bearer " + accessToken);
HttpEntity<String> emailsRequestEntity = new HttpEntity<>(null, emailsHeaders); HttpEntity<String> emailsRequestEntity = new HttpEntity<>(null, emailsHeaders);
ResponseEntity<List> emailsResponse = restTemplate.exchange( ResponseEntity<List> emailsResponse = restTemplate.exchange(
"https://api.github.com/user/emails", "https://api.github.com/user/emails",
HttpMethod.GET, HttpMethod.GET,
emailsRequestEntity, emailsRequestEntity,
List.class List.class
); );
List<Map<String, Object>> emails = emailsResponse.getBody(); List<Map<String, Object>> emails = emailsResponse.getBody();
String email = null; String email = null;
// Find primary email // Find primary email
for (Map<String, Object> emailInfo : emails) { for (Map<String, Object> emailInfo : emails) {
Boolean primary = (Boolean) emailInfo.get("primary"); Boolean primary = (Boolean) emailInfo.get("primary");
@ -132,22 +131,22 @@ public class GitHubService {
break; break;
} }
} }
// If no primary email, just use the first one // If no primary email, just use the first one
if (email == null && !emails.isEmpty()) { if (email == null && !emails.isEmpty()) {
email = (String) emails.get(0).get("email"); email = (String) emails.get(0).get("email");
} }
logger.info("Using email: {}", email); logger.info("Using email: {}", email);
// Process user data // Process user data
String githubId = userAttributes.get("id").toString(); String githubId = userAttributes.get("id").toString();
String username = (String) userAttributes.get("login"); String username = (String) userAttributes.get("login");
// Check if user exists by provider ID // Check if user exists by provider ID
Optional<UserEntity> userOptional = userRepository.findByProviderId(githubId); Optional<UserEntity> userOptional = userRepository.findByProviderId(githubId);
UserEntity user; UserEntity user;
if (userOptional.isPresent()) { if (userOptional.isPresent()) {
// Update existing user // Update existing user
user = userOptional.get(); user = userOptional.get();
@ -155,7 +154,7 @@ public class GitHubService {
} else { } else {
// Check if email exists // Check if email exists
userOptional = userRepository.findByEmail(email); userOptional = userRepository.findByEmail(email);
if (userOptional.isPresent()) { if (userOptional.isPresent()) {
user = userOptional.get(); user = userOptional.get();
user.setProvider(AuthProvider.GITHUB); user.setProvider(AuthProvider.GITHUB);
@ -169,7 +168,7 @@ public class GitHubService {
user.setProvider(AuthProvider.GITHUB); user.setProvider(AuthProvider.GITHUB);
user.setProviderId(githubId); user.setProviderId(githubId);
user.setEmailVerified(true); user.setEmailVerified(true);
user.setBalance(new BigDecimal("1000.00")); user.setBalance(new BigDecimal("1000.00"));
logger.info("Creating new user for: {}", username); logger.info("Creating new user for: {}", username);
} }
@ -177,7 +176,7 @@ public class GitHubService {
String randomPassword = UUID.randomUUID().toString(); String randomPassword = UUID.randomUUID().toString();
user.setPassword(oauth2PasswordEncoder.encode(randomPassword)); user.setPassword(oauth2PasswordEncoder.encode(randomPassword));
userRepository.save(user); userRepository.save(user);
Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), randomPassword)); Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), randomPassword));
@ -187,7 +186,7 @@ public class GitHubService {
logger.info("Generated JWT token"); logger.info("Generated JWT token");
return new AuthResponseDto(token); return new AuthResponseDto(token);
} catch (Exception e) { } catch (Exception e) {
logger.error("Error processing GitHub code", e); logger.error("Error processing GitHub code", e);
throw new RuntimeException("Failed to process GitHub authentication", e); throw new RuntimeException("Failed to process GitHub authentication", e);

View file

@ -1,8 +1,6 @@
package de.szut.casino.security; package de.szut.casino.security;
import de.szut.casino.security.jwt.JwtAuthenticationFilter; import de.szut.casino.security.jwt.JwtAuthenticationFilter;
import de.szut.casino.security.oauth2.CustomOAuth2UserService;
import de.szut.casino.security.oauth2.OAuth2AuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -33,7 +31,7 @@ public class SecurityConfig {
@Value("${app.frontend-host}") @Value("${app.frontend-host}")
private String frontendHost; private String frontendHost;
@Value("${app.oauth2.authorizedRedirectUris}") @Value("${app.oauth2.authorizedRedirectUris}")
private String authorizedRedirectUri; private String authorizedRedirectUri;
@ -42,15 +40,15 @@ public class SecurityConfig {
@Autowired @Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter; private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean @Bean
public DaoAuthenticationProvider authenticationProvider() { public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService); authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder()); authProvider.setPasswordEncoder(passwordEncoder());
return authProvider; return authProvider;
} }
@ -67,18 +65,18 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http http
.cors(cors -> cors.configurationSource(corsConfigurationSource())) .cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable()) .csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> { .authorizeHttpRequests(auth -> {
auth.requestMatchers("/auth/**", "/webhook", "/swagger/**", "/swagger-ui/**", "/health", "/error", "/oauth2/**").permitAll() auth.requestMatchers("/auth/**", "/webhook", "/swagger/**", "/swagger-ui/**", "/health", "/error", "/oauth2/**").permitAll()
.requestMatchers(org.springframework.http.HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers(org.springframework.http.HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest().authenticated(); .anyRequest().authenticated();
}) })
// Disable Spring's built-in OAuth2 login since we're implementing a custom flow // Disable Spring's built-in OAuth2 login since we're implementing a custom flow
// We're using our own GitHubController for OAuth2 login // We're using our own GitHubController for OAuth2 login
.authenticationProvider(authenticationProvider()) .authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build(); return http.build();
} }

View file

@ -12,7 +12,7 @@ import lombok.Setter;
public class AuthResponseDto { public class AuthResponseDto {
private String token; private String token;
private String tokenType = "Bearer"; private String tokenType = "Bearer";
public AuthResponseDto(String token) { public AuthResponseDto(String token) {
this.token = token; this.token = token;
} }

View file

@ -13,7 +13,7 @@ import lombok.Setter;
public class LoginRequestDto { public class LoginRequestDto {
@NotBlank(message = "Username or email is required") @NotBlank(message = "Username or email is required")
private String usernameOrEmail; private String usernameOrEmail;
@NotBlank(message = "Password is required") @NotBlank(message = "Password is required")
private String password; private String password;
} }

View file

@ -35,11 +35,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username); UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtUtils.validateToken(jwt, userDetails)) { if (jwtUtils.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities()); userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken); SecurityContextHolder.getContext().setAuthentication(authToken);
} }

View file

@ -24,7 +24,7 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {
@Autowired @Autowired
private UserRepository userRepository; private UserRepository userRepository;
@Autowired @Autowired
private PasswordEncoder oauth2PasswordEncoder; private PasswordEncoder oauth2PasswordEncoder;
@ -44,7 +44,7 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private OAuth2User processOAuth2User(OAuth2UserRequest oAuth2UserRequest, OAuth2User oAuth2User) { private OAuth2User processOAuth2User(OAuth2UserRequest oAuth2UserRequest, OAuth2User oAuth2User) {
String registrationId = oAuth2UserRequest.getClientRegistration().getRegistrationId(); String registrationId = oAuth2UserRequest.getClientRegistration().getRegistrationId();
OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(registrationId, oAuth2User.getAttributes()); OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(registrationId, oAuth2User.getAttributes());
// For GitHub, the email might not be directly available in attributes // For GitHub, the email might not be directly available in attributes
String email = oAuth2UserInfo.getEmail(); String email = oAuth2UserInfo.getEmail();
if (StringUtils.isEmpty(email)) { if (StringUtils.isEmpty(email)) {
@ -53,16 +53,16 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {
Optional<UserEntity> userOptional = userRepository.findByEmail(email); Optional<UserEntity> userOptional = userRepository.findByEmail(email);
UserEntity user; UserEntity user;
if(userOptional.isPresent()) { if (userOptional.isPresent()) {
user = userOptional.get(); user = userOptional.get();
if(!user.getProvider().equals(AuthProvider.valueOf(registrationId.toUpperCase()))) { if (!user.getProvider().equals(AuthProvider.valueOf(registrationId.toUpperCase()))) {
throw new OAuth2AuthenticationProcessingException("You're signed up with " + throw new OAuth2AuthenticationProcessingException("You're signed up with " +
user.getProvider() + ". Please use your " + user.getProvider() + user.getProvider() + ". Please use your " + user.getProvider() +
" account to login."); " account to login.");
} }
user = updateExistingUser(user, oAuth2UserInfo); user = updateExistingUser(user, oAuth2UserInfo);
} else { } else {
user = registerNewUser(oAuth2UserRequest, oAuth2UserInfo, email); user = registerNewUser(oAuth2UserRequest, oAuth2UserInfo, email);
@ -73,12 +73,12 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private UserEntity registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo, String email) { private UserEntity registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo, String email) {
UserEntity user = new UserEntity(); UserEntity user = new UserEntity();
String username = oAuth2UserInfo.getName(); String username = oAuth2UserInfo.getName();
if (StringUtils.isEmpty(username)) { if (StringUtils.isEmpty(username)) {
username = "github_" + oAuth2UserInfo.getId(); username = "github_" + oAuth2UserInfo.getId();
} }
// Check if username already exists and append a suffix if needed // Check if username already exists and append a suffix if needed
if (userRepository.findByUsername(username).isPresent()) { if (userRepository.findByUsername(username).isPresent()) {
username = username + "_" + UUID.randomUUID().toString().substring(0, 8); username = username + "_" + UUID.randomUUID().toString().substring(0, 8);
@ -89,13 +89,13 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {
user.setUsername(username); user.setUsername(username);
user.setEmail(email); user.setEmail(email);
user.setEmailVerified(true); user.setEmailVerified(true);
// Generate a random password for OAuth users (they won't use it) // Generate a random password for OAuth users (they won't use it)
String randomPassword = UUID.randomUUID().toString(); String randomPassword = UUID.randomUUID().toString();
user.setPassword(oauth2PasswordEncoder.encode(randomPassword)); user.setPassword(oauth2PasswordEncoder.encode(randomPassword));
user.setBalance(new BigDecimal("1000.00")); // Starting balance user.setBalance(new BigDecimal("1000.00")); // Starting balance
return userRepository.save(user); return userRepository.save(user);
} }

View file

@ -3,7 +3,7 @@ package de.szut.casino.security.oauth2;
import java.util.Map; import java.util.Map;
public class GitHubOAuth2UserInfo extends OAuth2UserInfo { public class GitHubOAuth2UserInfo extends OAuth2UserInfo {
public GitHubOAuth2UserInfo(Map<String, Object> attributes) { public GitHubOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes); super(attributes);
} }

View file

@ -1,7 +1,6 @@
package de.szut.casino.security.oauth2; package de.szut.casino.security.oauth2;
import de.szut.casino.security.jwt.JwtUtils; import de.szut.casino.security.jwt.JwtUtils;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserRepository; import de.szut.casino.user.UserRepository;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -26,7 +25,7 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS
@Autowired @Autowired
private JwtUtils jwtUtils; private JwtUtils jwtUtils;
@Autowired @Autowired
private UserRepository userRepository; private UserRepository userRepository;
@ -34,7 +33,7 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException { throws IOException, ServletException {
String targetUrl = determineTargetUrl(authentication); String targetUrl = determineTargetUrl(authentication);
logger.info("OAuth2 Authentication successful, redirecting to: {}", targetUrl); logger.info("OAuth2 Authentication successful, redirecting to: {}", targetUrl);
if (response.isCommitted()) { if (response.isCommitted()) {
@ -48,12 +47,12 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS
private String determineTargetUrl(Authentication authentication) { private String determineTargetUrl(Authentication authentication) {
String token = jwtUtils.generateToken(authentication); String token = jwtUtils.generateToken(authentication);
if (authentication.getPrincipal() instanceof UserPrincipal) { if (authentication.getPrincipal() instanceof UserPrincipal) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
logger.info("User authenticated: ID={}, Email={}", userPrincipal.getId(), userPrincipal.getEmail()); logger.info("User authenticated: ID={}, Email={}", userPrincipal.getId(), userPrincipal.getEmail());
} }
return UriComponentsBuilder.fromUriString(redirectUri) return UriComponentsBuilder.fromUriString(redirectUri)
.queryParam("token", token) .queryParam("token", token)
.build().toUriString(); .build().toUriString();

View file

@ -6,9 +6,9 @@ import de.szut.casino.user.AuthProvider;
import java.util.Map; import java.util.Map;
public class OAuth2UserInfoFactory { public class OAuth2UserInfoFactory {
public static OAuth2UserInfo getOAuth2UserInfo(String registrationId, Map<String, Object> attributes) { public static OAuth2UserInfo getOAuth2UserInfo(String registrationId, Map<String, Object> attributes) {
if(registrationId.equalsIgnoreCase(AuthProvider.GITHUB.toString())) { if (registrationId.equalsIgnoreCase(AuthProvider.GITHUB.toString())) {
return new GitHubOAuth2UserInfo(attributes); return new GitHubOAuth2UserInfo(attributes);
} else { } else {
throw new OAuth2AuthenticationProcessingException("Sorry! Login with " + registrationId + " is not supported yet."); throw new OAuth2AuthenticationProcessingException("Sorry! Login with " + registrationId + " is not supported yet.");

View file

@ -64,7 +64,7 @@ public class UserPrincipal implements OAuth2User, UserDetails {
// We're using email as the username for authentication // We're using email as the username for authentication
return email; return email;
} }
public String getDisplayUsername() { public String getDisplayUsername() {
return username; return username;
} }

View file

@ -20,17 +20,17 @@ public class UserDetailsServiceImpl implements UserDetailsService {
@Override @Override
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
Optional<UserEntity> user = userRepository.findByUsername(usernameOrEmail); Optional<UserEntity> user = userRepository.findByUsername(usernameOrEmail);
if (user.isEmpty()) { if (user.isEmpty()) {
user = userRepository.findByEmail(usernameOrEmail); user = userRepository.findByEmail(usernameOrEmail);
} }
UserEntity userEntity = user.orElseThrow(() -> UserEntity userEntity = user.orElseThrow(() ->
new UsernameNotFoundException("User not found with username or email: " + usernameOrEmail)); new UsernameNotFoundException("User not found with username or email: " + usernameOrEmail));
return new org.springframework.security.core.userdetails.User( return new org.springframework.security.core.userdetails.User(
userEntity.getUsername(), userEntity.getUsername(),
userEntity.getPassword(), userEntity.getPassword(),
new ArrayList<>()); new ArrayList<>());
} }
} }

View file

@ -1,11 +1,6 @@
package de.szut.casino.user; package de.szut.casino.user;
import jakarta.persistence.Column; import jakarta.persistence.*;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -20,15 +15,15 @@ public class UserEntity {
@Id @Id
@GeneratedValue @GeneratedValue
private Long id; private Long id;
@Column(unique = true) @Column(unique = true)
private String email; private String email;
@Column(unique = true) @Column(unique = true)
private String username; private String username;
private String password; private String password;
@Column(precision = 19, scale = 2) @Column(precision = 19, scale = 2)
private BigDecimal balance; private BigDecimal balance;
@ -37,10 +32,10 @@ public class UserEntity {
private String verificationToken; private String verificationToken;
private String passwordResetToken; private String passwordResetToken;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private AuthProvider provider = AuthProvider.LOCAL; private AuthProvider provider = AuthProvider.LOCAL;
private String providerId; private String providerId;
public UserEntity(String email, String username, String password, BigDecimal balance, String verificationToken) { public UserEntity(String email, String username, String password, BigDecimal balance, String verificationToken) {
@ -51,7 +46,7 @@ public class UserEntity {
this.verificationToken = verificationToken; this.verificationToken = verificationToken;
this.provider = AuthProvider.LOCAL; this.provider = AuthProvider.LOCAL;
} }
public UserEntity(String email, String username, AuthProvider provider, String providerId, BigDecimal balance) { public UserEntity(String email, String username, AuthProvider provider, String providerId, BigDecimal balance) {
this.email = email; this.email = email;
this.username = username; this.username = username;

View file

@ -5,7 +5,7 @@ import org.springframework.stereotype.Service;
@Service @Service
public class UserMappingService { public class UserMappingService {
public GetUserDto mapToGetUserDto(UserEntity user) { public GetUserDto mapToGetUserDto(UserEntity user) {
return new GetUserDto(user.getId(), user.getEmail(), user.getUsername(), user.getBalance()); return new GetUserDto(user.getId(), user.getEmail(), user.getUsername(), user.getBalance());
} }

View file

@ -9,13 +9,13 @@ import java.util.Optional;
@Service @Service
public interface UserRepository extends JpaRepository<UserEntity, Long> { public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByUsername(String username); Optional<UserEntity> findByUsername(String username);
Optional<UserEntity> findByEmail(String email); Optional<UserEntity> findByEmail(String email);
Optional<UserEntity> findByProviderId(String providerId); Optional<UserEntity> findByProviderId(String providerId);
boolean existsByUsername(String username); boolean existsByUsername(String username);
boolean existsByEmail(String email); boolean existsByEmail(String email);
@Query("SELECT u FROM UserEntity u WHERE u.verificationToken = ?1") @Query("SELECT u FROM UserEntity u WHERE u.verificationToken = ?1")

View file

@ -27,15 +27,15 @@ public class UserService {
if (userRepository.existsByEmail(createUserDto.getEmail())) { if (userRepository.existsByEmail(createUserDto.getEmail())) {
throw new EntityExistsException("Email is already in use"); throw new EntityExistsException("Email is already in use");
} }
UserEntity user = new UserEntity( UserEntity user = new UserEntity(
createUserDto.getEmail(), createUserDto.getEmail(),
createUserDto.getUsername(), createUserDto.getUsername(),
passwordEncoder.encode(createUserDto.getPassword()), passwordEncoder.encode(createUserDto.getPassword()),
BigDecimal.valueOf(100), BigDecimal.valueOf(100),
RandomStringUtils.randomAlphanumeric(64) RandomStringUtils.randomAlphanumeric(64)
); );
return userRepository.save(user); return userRepository.save(user);
} }
@ -50,7 +50,7 @@ public class UserService {
} }
public void saveUser(UserEntity user) { public void saveUser(UserEntity user) {
userRepository.save(user); userRepository.save(user);
} }
public boolean isVerified(String usernameOrEmail) { public boolean isVerified(String usernameOrEmail) {

View file

@ -16,11 +16,11 @@ public class CreateUserDto {
@NotBlank(message = "Email is required") @NotBlank(message = "Email is required")
@Email(message = "Email should be valid") @Email(message = "Email should be valid")
private String email; private String email;
@NotBlank(message = "Username is required") @NotBlank(message = "Username is required")
@Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters") @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
private String username; private String username;
@NotBlank(message = "Password is required") @NotBlank(message = "Password is required")
@Size(min = 6, message = "Password must be at least 6 characters") @Size(min = 6, message = "Password must be at least 6 characters")
private String password; private String password;

View file

@ -19,7 +19,7 @@ public class TransactionController {
@RequestHeader("Authorization") String authToken, @RequestHeader("Authorization") String authToken,
@RequestParam(value = "limit", required = false) Integer limit, @RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "offset", required = false) Integer offset @RequestParam(value = "offset", required = false) Integer offset
) { ) {
UserTransactionsDto transactionEntities = this.transactionService.getUserTransactionsDto(authToken, limit, offset); UserTransactionsDto transactionEntities = this.transactionService.getUserTransactionsDto(authToken, limit, offset);
return ResponseEntity.ok(transactionEntities); return ResponseEntity.ok(transactionEntities);