Skip to content

Commit

Permalink
[101] Stop fetching new OAuth metadata during each login
Browse files Browse the repository at this point in the history
Bug: #101
Signed-off-by: Stéphane Bégaudeau <[email protected]>
  • Loading branch information
sbegaudeau committed Jun 19, 2023
1 parent 2ff4e75 commit 4af982b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ public interface IAccountRepository extends PagingAndSortingRepository<Account,
Optional<Account> 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<Account> 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<Account> findByAccessKey(String accessKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Map<String, Object>> 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<Map<String, Object>> 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<OAuth2UserInfo> getUserInfo(String registrationId, OAuth2User oAuth2User, List<Map<String, Object>> additionalData) {
private OAuth2UserInfo getUserInfo(String registrationId, OAuth2User oAuth2User, List<Map<String, Object>> 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()));
Expand All @@ -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())
Expand Down

0 comments on commit 4af982b

Please sign in to comment.