Some checks failed
CI / Get Changed Files (pull_request) Successful in 8s
CI / oxlint (pull_request) Successful in 24s
CI / Docker frontend validation (pull_request) Successful in 26s
CI / eslint (pull_request) Successful in 31s
CI / prettier (pull_request) Failing after 32s
CI / Checkstyle Main (pull_request) Failing after 1m2s
CI / test-build (pull_request) Successful in 59s
CI / Docker backend validation (pull_request) Successful in 1m14s
165 lines
No EOL
6.1 KiB
Java
165 lines
No EOL
6.1 KiB
Java
package de.szut.casino.security;
|
|
|
|
import de.szut.casino.security.dto.AuthResponseDto;
|
|
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.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
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.security.authentication.AuthenticationManager;
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.*;
|
|
|
|
@Service
|
|
public class GitHubService {
|
|
@Value("${spring.security.oauth2.client.registration.github.client-id}")
|
|
private String clientId;
|
|
|
|
@Value("${spring.security.oauth2.client.registration.github.client-secret}")
|
|
private String clientSecret;
|
|
|
|
@Autowired
|
|
private AuthenticationManager authenticationManager;
|
|
|
|
@Autowired
|
|
private UserRepository userRepository;
|
|
|
|
@Autowired
|
|
private JwtUtils jwtUtils;
|
|
|
|
@Autowired
|
|
private PasswordEncoder oauth2PasswordEncoder;
|
|
|
|
public AuthResponseDto processGithubCode(String code) {
|
|
try {
|
|
RestTemplate restTemplate = new RestTemplate();
|
|
|
|
Map<String, String> requestBody = new HashMap<>();
|
|
requestBody.put("client_id", clientId);
|
|
requestBody.put("client_secret", clientSecret);
|
|
requestBody.put("code", code);
|
|
|
|
HttpHeaders headers = new HttpHeaders();
|
|
headers.set("Accept", "application/json");
|
|
|
|
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
|
|
|
|
ResponseEntity<Map> response = restTemplate.exchange(
|
|
"https://github.com/login/oauth/access_token",
|
|
HttpMethod.POST,
|
|
requestEntity,
|
|
Map.class
|
|
);
|
|
|
|
Map<String, Object> responseBody = response.getBody();
|
|
|
|
if (responseBody.containsKey("error")) {
|
|
String error = (String) responseBody.get("error");
|
|
String errorDescription = (String) responseBody.get("error_description");
|
|
|
|
throw new RuntimeException("GitHub OAuth error: " + errorDescription);
|
|
}
|
|
|
|
String accessToken = (String) responseBody.get("access_token");
|
|
if (accessToken == null || accessToken.isEmpty()) {
|
|
|
|
throw new RuntimeException("Failed to receive access token from GitHub");
|
|
}
|
|
|
|
HttpHeaders userInfoHeaders = new HttpHeaders();
|
|
userInfoHeaders.set("Authorization", "Bearer " + accessToken);
|
|
|
|
HttpEntity<String> userInfoRequestEntity = new HttpEntity<>(null, userInfoHeaders);
|
|
|
|
ResponseEntity<Map> userResponse = restTemplate.exchange(
|
|
"https://api.github.com/user",
|
|
HttpMethod.GET,
|
|
userInfoRequestEntity,
|
|
Map.class
|
|
);
|
|
|
|
Map<String, Object> userAttributes = userResponse.getBody();
|
|
|
|
HttpHeaders emailsHeaders = new HttpHeaders();
|
|
emailsHeaders.set("Authorization", "Bearer " + accessToken);
|
|
|
|
HttpEntity<String> emailsRequestEntity = new HttpEntity<>(null, emailsHeaders);
|
|
|
|
ResponseEntity<List> emailsResponse = restTemplate.exchange(
|
|
"https://api.github.com/user/emails",
|
|
HttpMethod.GET,
|
|
emailsRequestEntity,
|
|
List.class
|
|
);
|
|
|
|
List<Map<String, Object>> emails = emailsResponse.getBody();
|
|
String email = null;
|
|
|
|
for (Map<String, Object> emailInfo : emails) {
|
|
Boolean primary = (Boolean) emailInfo.get("primary");
|
|
if (primary != null && primary) {
|
|
email = (String) emailInfo.get("email");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (email == null && !emails.isEmpty()) {
|
|
email = (String) emails.get(0).get("email");
|
|
}
|
|
|
|
String githubId = userAttributes.get("id").toString();
|
|
String username = (String) userAttributes.get("login");
|
|
|
|
Optional<UserEntity> userOptional = userRepository.findByProviderId(githubId);
|
|
UserEntity user;
|
|
|
|
if (userOptional.isPresent()) {
|
|
user = userOptional.get();
|
|
} else {
|
|
userOptional = userRepository.findByEmail(email);
|
|
|
|
if (userOptional.isPresent()) {
|
|
user = userOptional.get();
|
|
user.setProvider(AuthProvider.GITHUB);
|
|
user.setProviderId(githubId);
|
|
} else {
|
|
user = new UserEntity();
|
|
user.setEmail(email);
|
|
user.setUsername(username);
|
|
user.setProvider(AuthProvider.GITHUB);
|
|
user.setProviderId(githubId);
|
|
user.setEmailVerified(true);
|
|
|
|
user.setBalance(new BigDecimal("1000.00"));
|
|
}
|
|
}
|
|
|
|
String randomPassword = UUID.randomUUID().toString();
|
|
user.setPassword(oauth2PasswordEncoder.encode(randomPassword));
|
|
|
|
userRepository.save(user);
|
|
|
|
Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), randomPassword));
|
|
|
|
String token = jwtUtils.generateToken(authentication);
|
|
|
|
return new AuthResponseDto(token);
|
|
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Failed to process GitHub authentication", e);
|
|
}
|
|
}
|
|
} |