OAuthTokenCache: Use account id as key
Current implementation assumes that OAuth provider always exposes user name by using it for key in OAuth token cache. For some OAuth providers (most notably Google OAuth provider) this is not the case. Move from using user name to account id for token cache key. Postpone populating the cache to the point when the authentication already took place and use returned account id as cache key. Bug: Issue 4627 Change-Id: I59f15b7c5ca8be6d52b59d21fac58cba88ba7fe3
This commit is contained in:
		@@ -18,6 +18,7 @@ import com.google.gerrit.extensions.auth.oauth.OAuthToken;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestReadView;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.auth.oauth.OAuthTokenCache;
 | 
			
		||||
import com.google.gerrit.server.config.CanonicalWebUrl;
 | 
			
		||||
@@ -52,16 +53,13 @@ class GetOAuthToken implements RestReadView<AccountResource>{
 | 
			
		||||
    if (self.get() != rsrc.getUser()) {
 | 
			
		||||
      throw new AuthException("not allowed to get access token");
 | 
			
		||||
    }
 | 
			
		||||
    String username = rsrc.getUser().getAccount().getUserName();
 | 
			
		||||
    if (username == null) {
 | 
			
		||||
      throw new ResourceNotFoundException();
 | 
			
		||||
    }
 | 
			
		||||
    OAuthToken accessToken = tokenCache.get(username);
 | 
			
		||||
    Account a = rsrc.getUser().getAccount();
 | 
			
		||||
    OAuthToken accessToken = tokenCache.get(a.getId());
 | 
			
		||||
    if (accessToken == null) {
 | 
			
		||||
      throw new ResourceNotFoundException();
 | 
			
		||||
    }
 | 
			
		||||
    OAuthTokenInfo accessTokenInfo = new OAuthTokenInfo();
 | 
			
		||||
    accessTokenInfo.username = username;
 | 
			
		||||
    accessTokenInfo.username = a.getUserName();
 | 
			
		||||
    accessTokenInfo.resourceHost = hostName;
 | 
			
		||||
    accessTokenInfo.accessToken = accessToken.getToken();
 | 
			
		||||
    accessTokenInfo.providerId = accessToken.getProviderId();
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
import com.google.common.cache.Cache;
 | 
			
		||||
import com.google.gerrit.extensions.auth.oauth.OAuthToken;
 | 
			
		||||
import com.google.gerrit.extensions.auth.oauth.OAuthTokenEncrypter;
 | 
			
		||||
import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo;
 | 
			
		||||
import com.google.gerrit.extensions.registration.DynamicItem;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.server.cache.CacheModule;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Module;
 | 
			
		||||
@@ -37,54 +37,39 @@ public class OAuthTokenCache {
 | 
			
		||||
    return new CacheModule() {
 | 
			
		||||
      @Override
 | 
			
		||||
      protected void configure() {
 | 
			
		||||
        persist(OAUTH_TOKENS, String.class, OAuthToken.class);
 | 
			
		||||
        persist(OAUTH_TOKENS, Account.Id.class, OAuthToken.class);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private final Cache<String, OAuthToken> cache;
 | 
			
		||||
  private final Cache<Account.Id, OAuthToken> cache;
 | 
			
		||||
 | 
			
		||||
  @Inject
 | 
			
		||||
  OAuthTokenCache(@Named(OAUTH_TOKENS) Cache<String, OAuthToken> cache,
 | 
			
		||||
  OAuthTokenCache(@Named(OAUTH_TOKENS) Cache<Account.Id, OAuthToken> cache,
 | 
			
		||||
      DynamicItem<OAuthTokenEncrypter> encrypter) {
 | 
			
		||||
    this.cache = cache;
 | 
			
		||||
    this.encrypter = encrypter;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean has(OAuthUserInfo user) {
 | 
			
		||||
    return user != null
 | 
			
		||||
      ? cache.getIfPresent(user.getUserName()) != null
 | 
			
		||||
      : false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public OAuthToken get(OAuthUserInfo user) {
 | 
			
		||||
    return user != null
 | 
			
		||||
      ? get(user.getUserName())
 | 
			
		||||
      : null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public OAuthToken get(String userName) {
 | 
			
		||||
    OAuthToken accessToken = cache.getIfPresent(userName);
 | 
			
		||||
  public OAuthToken get(Account.Id id) {
 | 
			
		||||
    OAuthToken accessToken = cache.getIfPresent(id);
 | 
			
		||||
    if (accessToken == null) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    accessToken = decrypt(accessToken);
 | 
			
		||||
    if (accessToken.isExpired()) {
 | 
			
		||||
      cache.invalidate(userName);
 | 
			
		||||
      cache.invalidate(id);
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    return accessToken;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void put(OAuthUserInfo user, OAuthToken accessToken) {
 | 
			
		||||
    cache.put(checkNotNull(user.getUserName()),
 | 
			
		||||
        encrypt(checkNotNull(accessToken)));
 | 
			
		||||
  public void put(Account.Id id, OAuthToken accessToken) {
 | 
			
		||||
    cache.put(id, encrypt(checkNotNull(accessToken)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void remove(OAuthUserInfo user) {
 | 
			
		||||
    if (user != null) {
 | 
			
		||||
      cache.invalidate(user.getUserName());
 | 
			
		||||
    }
 | 
			
		||||
  public void remove(Account.Id id) {
 | 
			
		||||
    cache.invalidate(id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private OAuthToken encrypt(OAuthToken token) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user