Skip to content

Commit

Permalink
Update the cached token info so it indicate if the token is an OBO one (
Browse files Browse the repository at this point in the history
#7196)

* Update the cached token info so it indicate if the token is an OBO one

* Fix unit tests
  • Loading branch information
amontenegro authored Feb 5, 2025
1 parent 2e46343 commit fd249e1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
package org.orcid.api.common.filter;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;

import org.apache.commons.lang3.StringUtils;
import org.orcid.core.constants.OrcidOauth2Constants;
import org.orcid.core.exception.OboNotValidForApiVersionException;
import org.orcid.core.oauth.OrcidOauth2TokenDetailService;
import org.orcid.core.utils.JsonUtils;
import org.orcid.core.utils.cache.redis.RedisClient;
import org.orcid.persistence.jpa.entities.OrcidOauth2TokenDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Component;


@Component
@Provider
public class OboApiVersionCheckFilter implements ContainerRequestFilter {

@Autowired
private OrcidOauth2TokenDetailService orcidOauth2TokenService;


@Autowired
private RedisClient redisClient;

@Value("${org.orcid.core.utils.cache.redis.enabled:true}")
private boolean isTokenCacheEnabled;

@Override
public void filter(ContainerRequestContext request) {
String version = getApiVersion(request);
Expand All @@ -44,9 +57,19 @@ private boolean isOboRequest() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (OAuth2Authentication.class.isAssignableFrom(authentication.getClass())) {
OAuth2AuthenticationDetails authDetails = (OAuth2AuthenticationDetails) ((OAuth2Authentication) authentication).getDetails();
if (authDetails != null && authDetails.getTokenValue() != null) {
OrcidOauth2TokenDetail tokenDetail = orcidOauth2TokenService.findIgnoringDisabledByTokenValue(authDetails.getTokenValue());
return tokenDetail.getOboClientDetailsId() != null;
if (authDetails != null && authDetails.getTokenValue() != null) {
Map<String, String> cachedAccessToken = getTokenFromCache(authDetails.getTokenValue());
if(cachedAccessToken != null) {
if(cachedAccessToken.containsKey(OrcidOauth2Constants.IS_OBO_TOKEN)) {
return true;
}
} else {
// Fallback to database if it is not in the cache
OrcidOauth2TokenDetail tokenDetail = orcidOauth2TokenService.findIgnoringDisabledByTokenValue(authDetails.getTokenValue());
if(tokenDetail != null) {
return tokenDetail.getOboClientDetailsId() != null;
}
}
}
}
}
Expand All @@ -62,4 +85,14 @@ private String getApiVersion(ContainerRequestContext request) {
return null;
}

private Map<String, String> getTokenFromCache(String accessTokenValue) {
if(isTokenCacheEnabled) {
String tokenJsonInfo = redisClient.get(accessTokenValue);
if(StringUtils.isNotBlank(tokenJsonInfo)) {
return JsonUtils.readObjectFromJsonString(tokenJsonInfo, HashMap.class);
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.orcid.persistence.dao.ProfileLastModifiedDao;
import org.orcid.persistence.jpa.entities.IndexingStatus;
import org.orcid.persistence.jpa.entities.OrcidOauth2AuthoriziationCodeDetail;
import org.orcid.persistence.jpa.entities.OrcidOauth2TokenDetail;
import org.orcid.pojo.ajaxForm.PojoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -191,6 +192,9 @@ protected void setToCache(String clientId, OAuth2AccessToken accessToken) {
tokenData.put(OrcidOauth2Constants.CLIENT_ID, clientId);
tokenData.put(OrcidOauth2Constants.RESOURCE_IDS, OrcidOauth2Constants.ORCID);
tokenData.put(OrcidOauth2Constants.APPROVED, Boolean.TRUE.toString());
if(accessToken.getAdditionalInformation().containsKey(OrcidOauth2Constants.IS_OBO_TOKEN)) {
tokenData.put(OrcidOauth2Constants.IS_OBO_TOKEN, Boolean.TRUE.toString());
}
redisClient.set(tokenValue, JsonUtils.convertToJsonString(tokenData));
} catch(Exception e) {
LOGGER.info("Unable to set token in Redis cache", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class OrcidOauth2Constants {
public static final String GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
public static final String DATE_CREATED = "date_created";
public static final String CLIENT_ID = "client_id";
public static final String IS_OBO_TOKEN = "is_obo_token";
public static final String ORCID = "orcid";
public static final String NAME = "name";
public static final String CLIENT_ID_PARAM = "client_id";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.nimbusds.jwt.SignedJWT;

import static org.orcid.core.constants.OrcidOauth2Constants.TOKEN_DISABLED;
import static org.orcid.core.constants.OrcidOauth2Constants.IS_OBO_TOKEN;

public class IETFTokenExchangeResponse implements OAuth2AccessToken {

Expand Down Expand Up @@ -52,6 +53,10 @@ public static IETFTokenExchangeResponse accessToken(OAuth2AccessToken accessTok
if(accessToken.getAdditionalInformation().containsKey(TOKEN_DISABLED)) {
token.additionalInformation.put(TOKEN_DISABLED, "true");
}
if(accessToken.getAdditionalInformation().containsKey(IS_OBO_TOKEN)) {
token.additionalInformation.put(IS_OBO_TOKEN, "true");
}

return token;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authe
orcidOauthTokenDetailService.createNew(detail);
// Set the token id in the additional details
token.getAdditionalInformation().put(OrcidOauth2Constants.TOKEN_ID, detail.getId());
if(detail.getOboClientDetailsId() != null) {
token.getAdditionalInformation().put(OrcidOauth2Constants.IS_OBO_TOKEN, "true");
}
}

/**
Expand Down

0 comments on commit fd249e1

Please sign in to comment.