Package org.opensocial.explorer.server.oauth2

Source Code of org.opensocial.explorer.server.oauth2.OSEOAuth2Store

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.opensocial.explorer.server.oauth2;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import org.apache.shindig.common.crypto.BlobCrypter;
import org.apache.shindig.common.servlet.Authority;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.GadgetException.Code;
import org.apache.shindig.gadgets.oauth2.BasicOAuth2Accessor;
import org.apache.shindig.gadgets.oauth2.BasicOAuth2Store;
import org.apache.shindig.gadgets.oauth2.OAuth2Accessor;
import org.apache.shindig.gadgets.oauth2.OAuth2CallbackState;
import org.apache.shindig.gadgets.oauth2.OAuth2FetcherConfig;
import org.apache.shindig.gadgets.oauth2.OAuth2Store;
import org.apache.shindig.gadgets.oauth2.OAuth2Token;
import org.apache.shindig.gadgets.oauth2.logger.FilteredLogger;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2CacheException;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Client;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Encrypter;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2PersistenceException;
import org.apache.wink.json4j.JSONArray;
import org.apache.wink.json4j.JSONException;
import org.opensocial.explorer.server.oauth.NoSuchStoreException;

import java.io.UnsupportedEncodingException;

/**
* see {@link OAuth2Store}
*
* Default OAuth2Store.  Handles a persistence scenario with a separate cache
* and persistence layer.
*
* Uses 3 Guice bindings to achieve storage implementation.
*
* 1) {@link IOAuth2Persister} 2) {@link IOAuth2Cache} 3) {@link OAuth2Encrypter}
*
*/
public class OSEOAuth2Store extends BasicOAuth2Store {
  private static final String LOG_CLASS = OSEOAuth2Store.class.getName();
  private static final FilteredLogger LOG = FilteredLogger
          .getFilteredLogger(OSEOAuth2Store.LOG_CLASS);

  private final IOAuth2Cache cache;
  private final IOAuth2Persister persister;
  private final String globalRedirectUri;
  private final Authority authority;
  private final String contextRoot;
  private final BlobCrypter stateCrypter;

  @Inject
  public OSEOAuth2Store(final IOAuth2Cache cache, final IOAuth2Persister persister,
          final OAuth2Encrypter encrypter, final String globalRedirectUri,
          final Authority authority, final String contextRoot,
          @Named(OAuth2FetcherConfig.OAUTH2_STATE_CRYPTER) final BlobCrypter stateCrypter) {
    super(cache, persister, encrypter, globalRedirectUri, authority, contextRoot, stateCrypter);

    this.cache = cache;
    this.persister = persister;
    this.globalRedirectUri = globalRedirectUri;
    this.authority = authority;
    this.contextRoot = contextRoot;
    this.stateCrypter = stateCrypter;
  }
 
  /**
   * Used to extract a client with the matching userId that is in the userStore.
   * If the client exists in the userClientStore, getUserClient is called.
   * Else, it calls the 2 parameter getClient to check the anonymous OAuth2Client store.
   *
   * @param userId The user ID.
   * @param gadgetUri The uri of the gadget.
   * @param serviceName The name of the client.
   * @return The OAuth2Client matching the userId and serviceName.
   */
  public OAuth2Client getClient(final String userId, final String gadgetUri, final String serviceName)
          throws GadgetException {
    final boolean isLogging = OSEOAuth2Store.LOG.isLoggable();
    OAuth2Client client;
    if (isLogging) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "getClient", new Object[] {
              gadgetUri, serviceName });
    }
   
    // check in cache's user map
    if(this.cache.isUserExisting(userId)) {
      client = this.cache.getUserClient(userId, serviceName);
    // else check cache's anon map
    } else {
      client = this.cache.getClient(gadgetUri, serviceName);
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.log("client from cache = {0}", client);
    }

    if (client == null) {
      try {
        // check in persister's user map
        if(this.persister.isUserExisting(userId)) {
          client = this.persister.getUserClient(userId, serviceName);
        // else check persister's anon map
        } else {
          client = this.persister.findClient(gadgetUri, serviceName);
        }
        if (client != null) {
          this.cache.storeClient(client);
        }
      } catch (final OAuth2PersistenceException e) {
        if (isLogging) {
          OSEOAuth2Store.LOG.log("Error loading OAuth2 client ", e);
        }
        throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error loading OAuth2 client "
                + serviceName, e);
      }
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "getClient", client);
    }

    return client;
  }
 
  /**
   * Gets all the clients associated with the given userId in both the cache and persister.
   * Returns an empty JSONArray if user doesn't exist or user has no clients in either layer.
   * @param userId The user ID.
   * @throws UnsupportedEncodingException
   */
  public JSONArray getUserClients(String userId) throws JSONException, UnsupportedEncodingException {
    return this.cache.getUserClients(userId);
  }
 
  /**
   * Adds a client with the given serviceName to the given userId.
   * Overwrites the client if it already exists.
   * @param userId The user ID.
   * @param serviceName The name of the client.
   * @param client The container class with all of the client's information.
   */
  public void addUserClient(String userId, String serviceName, OAuth2Client client) {
    this.cache.addUserClient(userId, serviceName, client);
    this.persister.addUserClient(userId, serviceName, client);
  }
 
  /**
   * Deletes a client with the given serviceName associated with the given userId.
   * Throws an exception if the userId does not exist in the userStore.
   * @param userId The user ID.
   * @param serviceName The name of the client.
   */
  public void deleteUserClient(String userId, String serviceName) throws NoSuchStoreException {
    this.cache.deleteUserClient(userId, serviceName);
    this.persister.deleteUserClient(userId, serviceName);
  }
  
  public OAuth2Accessor getOAuth2Accessor(final String gadgetUri, final String serviceName,
      final String user, final String scope) throws GadgetException {
    final boolean isLogging = OSEOAuth2Store.LOG.isLoggable();
    if (isLogging) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "getOAuth2Accessor", new Object[] {
          gadgetUri, serviceName, user, scope });
    }

    final OAuth2CallbackState state = new OAuth2CallbackState(this.stateCrypter);
    state.setGadgetUri(gadgetUri);
    state.setServiceName(serviceName);
    state.setUser(user);
    state.setScope(scope);

    OAuth2Accessor ret = this.cache.getOAuth2Accessor(state);

    if (ret == null || !ret.isValid()) {
      final OAuth2Client client = this.getClient(user, gadgetUri, serviceName);

      if (client != null) {
        final OAuth2Token accessToken = this.getToken(gadgetUri, serviceName, user, scope,
            OAuth2Token.Type.ACCESS);
        final OAuth2Token refreshToken = this.getToken(gadgetUri, serviceName, user, scope,
            OAuth2Token.Type.REFRESH);

        final BasicOAuth2Accessor newAccessor = new BasicOAuth2Accessor(gadgetUri, serviceName,
            user, scope, client.isAllowModuleOverride(), this, this.globalRedirectUri,
            this.authority, this.contextRoot);
        newAccessor.setAccessToken(accessToken);
        newAccessor.setAuthorizationUrl(client.getAuthorizationUrl());
        newAccessor.setClientAuthenticationType(client.getClientAuthenticationType());
        newAccessor.setAuthorizationHeader(client.isAuthorizationHeader());
        newAccessor.setUrlParameter(client.isUrlParameter());
        newAccessor.setClientId(client.getClientId());
        newAccessor.setClientSecret(client.getClientSecret());
        newAccessor.setGrantType(client.getGrantType());
        newAccessor.setRedirectUri(client.getRedirectUri());
        newAccessor.setRefreshToken(refreshToken);
        newAccessor.setTokenUrl(client.getTokenUrl());
        newAccessor.setType(client.getType());
        newAccessor.setAllowedDomains(client.getAllowedDomains());
        ret = newAccessor;

        this.storeOAuth2Accessor(ret);
      }
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "getOAuth2Accessor", ret);
    }

    return ret;
  }
 
  public OAuth2Token getToken(final String gadgetUri, final String serviceName, final String user,
          final String scope, final OAuth2Token.Type type) throws GadgetException {

    final boolean isLogging = OSEOAuth2Store.LOG.isLoggable();
    if (isLogging) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "getToken", new Object[] {
              gadgetUri, serviceName, user, scope, type });
    }

    final String processedGadgetUri = this.getGadgetUri(user, gadgetUri, serviceName);
    OAuth2Token token = this.cache.getToken(processedGadgetUri, serviceName, user, scope, type);
    if (token == null) {
      try {
        token = this.persister.findToken(processedGadgetUri, serviceName, user, scope, type);
        if (token != null) {
          synchronized (token) {
            try {
              token.setGadgetUri(processedGadgetUri);
              this.cache.storeToken(token);
            } finally {
              token.setGadgetUri(gadgetUri);
            }
          }
        }
      } catch (final OAuth2PersistenceException e) {
        throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error loading OAuth2 token", e);
      }
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "getToken", token);
    }

    return token;
  }

  public OAuth2Token removeToken(final OAuth2Token token) throws GadgetException {
    final boolean isLogging = OSEOAuth2Store.LOG.isLoggable();
    if (isLogging) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "removeToken", token);
    }

    if (token != null) {
      if (isLogging) {
        OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "removeToken", token);
      }

      try {
        synchronized (token) {
          final String origGadgetApi = token.getGadgetUri();
          final String processedGadgetUri = this.getGadgetUri(token.getUser(), token.getGadgetUri(), token.getServiceName());
          token.setGadgetUri(processedGadgetUri);
          try {
            // Remove token from the cache
            this.cache.removeToken(token);
            // Token is gone from the cache, also remove it from persistence
            this.persister.removeToken(processedGadgetUri, token.getServiceName(), token.getUser(), token.getScope(), token.getType());
          } finally {
            token.setGadgetUri(origGadgetApi);
          }
        }

        return token;
      } catch (final OAuth2PersistenceException e) {
        if (isLogging) {
          OSEOAuth2Store.LOG.log("Error removing OAuth2 token ", e);
        }
        throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error removing OAuth2 token "
                + token.getServiceName(), e);
      }
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "removeToken", null);
    }

    return null;
  }

  public static boolean runImport(final IOAuth2Persister source, final IOAuth2Persister target,
          final boolean clean) {
    if (OSEOAuth2Store.LOG.isLoggable()) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "runImport", new Object[] { source,
              target, clean });
    }

    // No import for default persistence
    return false;
  }

  public void setToken(final OAuth2Token token) throws GadgetException {
    final boolean isLogging = OSEOAuth2Store.LOG.isLoggable();
    if (isLogging) {
      OSEOAuth2Store.LOG.entering(OSEOAuth2Store.LOG_CLASS, "setToken", token);
    }

    if (token != null) {
      final String gadgetUri = token.getGadgetUri();
      final String serviceName = token.getServiceName();

      final String processedGadgetUri = this.getGadgetUri(token.getUser(), gadgetUri, serviceName);
      synchronized (token) {
        token.setGadgetUri(processedGadgetUri);
        try {
          final OAuth2Token existingToken = this.getToken(gadgetUri, token.getServiceName(),
                  token.getUser(), token.getScope(), token.getType());
          try {
            if (existingToken == null) {
              this.persister.insertToken(token);
            } else {
              synchronized (existingToken) {
                try {
                  existingToken.setGadgetUri(processedGadgetUri);
                  this.cache.removeToken(existingToken);
                  this.persister.updateToken(token);
                } finally {
                  existingToken.setGadgetUri(gadgetUri);
                }
              }
            }
            this.cache.storeToken(token);
          } catch (final OAuth2CacheException e) {
            if (isLogging) {
              OSEOAuth2Store.LOG.log("Error storing OAuth2 token", e);
            }
            throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error storing OAuth2 token", e);
          } catch (final OAuth2PersistenceException e) {
            if (isLogging) {
              OSEOAuth2Store.LOG.log("Error storing OAuth2 token", e);
            }
            throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error storing OAuth2 token", e);
          }
        } finally {
          token.setGadgetUri(gadgetUri);
        }
      }
    }

    if (isLogging) {
      OSEOAuth2Store.LOG.exiting(OSEOAuth2Store.LOG_CLASS, "setToken");
    }
  }

  protected String getGadgetUri(final String userId, final String gadgetUri, final String serviceName)
          throws GadgetException {
    String ret = gadgetUri;
    final OAuth2Client client = this.getClient(ret, serviceName);
    if (client != null) {
      if (client.isSharedToken()) {
        ret = client.getClientId() + ':' + client.getServiceName();
      }
    }

    return ret;
  }
}
TOP

Related Classes of org.opensocial.explorer.server.oauth2.OSEOAuth2Store

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.