diff --git a/backend/svalyn-studio-domain/src/main/java/com/svalyn/studio/domain/account/repositories/IAccountRepository.java b/backend/svalyn-studio-domain/src/main/java/com/svalyn/studio/domain/account/repositories/IAccountRepository.java index ea3656c..8c41b6d 100644 --- a/backend/svalyn-studio-domain/src/main/java/com/svalyn/studio/domain/account/repositories/IAccountRepository.java +++ b/backend/svalyn-studio-domain/src/main/java/com/svalyn/studio/domain/account/repositories/IAccountRepository.java @@ -39,7 +39,15 @@ public interface IAccountRepository extends PagingAndSortingRepository findByEmail(String email); @Query(""" - SELECT * FROM account account JOIN authentication_token authenticationToken ON account.id = authenticationToken.account_id + SELECT * FROM account account + JOIN oauth2_metadata oauth2 ON account.id = oauth2.account_id + WHERE oauth2.provider = :provider AND oauth2.provider_id = :providerId + """) + Optional findByOAuth2Metadata(String provider, String providerId); + + @Query(""" + SELECT * FROM account account + JOIN authentication_token authenticationToken ON account.id = authenticationToken.account_id WHERE authenticationToken.access_key = :accessKey AND authenticationToken.status = 'ACTIVE' """) Optional findByAccessKey(String accessKey); diff --git a/backend/svalyn-studio-infrastructure/src/main/java/com/svalyn/studio/infrastructure/security/SvalynOAuth2UserService.java b/backend/svalyn-studio-infrastructure/src/main/java/com/svalyn/studio/infrastructure/security/SvalynOAuth2UserService.java index 188a6a2..f497384 100644 --- a/backend/svalyn-studio-infrastructure/src/main/java/com/svalyn/studio/infrastructure/security/SvalynOAuth2UserService.java +++ b/backend/svalyn-studio-infrastructure/src/main/java/com/svalyn/studio/infrastructure/security/SvalynOAuth2UserService.java @@ -65,50 +65,50 @@ public SvalynOAuth2UserService(IAccountRepository accountRepository, WebClient w public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); - this.logger.debug("Data retrieved for user " + userRequest.getClientRegistration().getRegistrationId() + "#" + oAuth2User.getAttributes().get("id")); - - OAuth2AuthorizedClient client = new OAuth2AuthorizedClient(userRequest.getClientRegistration(), oAuth2User.getName(), userRequest.getAccessToken()); - List> additionalData = new ArrayList<>(); - - if (userRequest.getClientRegistration().getRegistrationId().equalsIgnoreCase("github")) { - additionalData = webClient.get() - .uri("https://api.github.com/user/emails") - .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient(client)) - .retrieve() - .bodyToMono(List.class) - .block(); - } - - var optionalOAuth2UserInfo = this.getUserInfo(userRequest.getClientRegistration().getRegistrationId(), oAuth2User, additionalData); + var provider = userRequest.getClientRegistration().getRegistrationId(); + var providerId = Optional.ofNullable(oAuth2User.getAttributes().get("id")).map(Object::toString).orElse(""); - if (optionalOAuth2UserInfo.isEmpty()) { - this.logger.debug("OAuth2UserInfo empty"); - throw new OAuth2AuthenticationException("The OAuth2 provider " + userRequest.getClientRegistration().getRegistrationId() + ", used for the authentication, is not supported"); - } + this.logger.debug("Data retrieved for user {}#{}", provider, providerId); - var oAuth2UserInfo = optionalOAuth2UserInfo.get(); Account account; - var optionalExistingAccountEntity = this.accountRepository.findByEmail(oAuth2UserInfo.getEmail()); + var optionalExistingAccountEntity = this.accountRepository.findByOAuth2Metadata(provider, providerId); if (optionalExistingAccountEntity.isPresent()) { var existingAccountEntity = optionalExistingAccountEntity.get(); + + var oAuth2UserInfo = this.getUserInfo(userRequest.getClientRegistration().getRegistrationId(), oAuth2User, List.of()); account = this.updateAccount(existingAccountEntity, userRequest, oAuth2UserInfo); } else { + OAuth2AuthorizedClient client = new OAuth2AuthorizedClient(userRequest.getClientRegistration(), oAuth2User.getName(), userRequest.getAccessToken()); + List> additionalData = new ArrayList<>(); + + if (userRequest.getClientRegistration().getRegistrationId().equalsIgnoreCase("github")) { + additionalData = webClient.get() + .uri("https://api.github.com/user/emails") + .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient(client)) + .retrieve() + .bodyToMono(List.class) + .block(); + } + + var oAuth2UserInfo = this.getUserInfo(userRequest.getClientRegistration().getRegistrationId(), oAuth2User, additionalData); account = this.createAccount(userRequest, oAuth2UserInfo); } return new SvalynOAuth2User(account, oAuth2User, userRequest.getAccessToken()); } - private Optional getUserInfo(String registrationId, OAuth2User oAuth2User, List> additionalData) { + private OAuth2UserInfo getUserInfo(String registrationId, OAuth2User oAuth2User, List> additionalData) { if (registrationId.equalsIgnoreCase("github")) { - return Optional.of(new GithubOAuth2UserInfo(oAuth2User.getAttributes(), additionalData)); + return new GithubOAuth2UserInfo(oAuth2User.getAttributes(), additionalData); } - return Optional.empty(); + + this.logger.debug("OAuth2UserInfo empty"); + throw new OAuth2AuthenticationException("The OAuth2 provider " + registrationId + ", used for the authentication, is not supported"); } private Account updateAccount(Account account, OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo) { - this.logger.debug("Updating account " + oAuth2UserRequest.getClientRegistration().getRegistrationId() + "#" + oAuth2UserInfo.getId()); + this.logger.debug("Updating account {}#{}", oAuth2UserRequest.getClientRegistration().getRegistrationId(), oAuth2UserInfo.getId()); var hasLoggedWithProvider = account.getOAuth2Metadata().stream() .anyMatch(oAuth2Metadata -> oAuth2Metadata.getProvider().equalsIgnoreCase(oAuth2UserRequest.getClientRegistration().getRegistrationId())); @@ -127,7 +127,7 @@ private Account updateAccount(Account account, OAuth2UserRequest oAuth2UserReque } private Account createAccount(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo) { - this.logger.debug("Creating account " + oAuth2UserRequest.getClientRegistration().getRegistrationId() + "#" + oAuth2UserInfo.getId()); + this.logger.debug("Creating account {}#{}", oAuth2UserRequest.getClientRegistration().getRegistrationId(), oAuth2UserInfo.getId()); var oAuth2Metadata = OAuth2Metadata.newOAuth2Metadata() .provider(oAuth2UserRequest.getClientRegistration().getRegistrationId())