/** * OAuth authenticated fetch. */ public sResponse fetch(sRequest request) { realRequest = request; clientState = new OAuthClientState( fetcherConfig.getStateCrypter(), request.getOAuthArguments().getOrigClientState()); responseParams = new OAuthResponseParams(request.getSecurityToken(), request, fetcherConfig.getStateCrypter()); try { return(fetchNoThrow()); } catch (Exception e) { // We log here to record the request/response pairs that created the failure. responseParams.logDetailedWarning("OAuth fetch unexpected fatal error", e); throw e; } }
/** * Retrieve an AccessorInfo and OAuthAccessor that are ready for signing OAuthMessages. To do * this, we need to figure out: * * - what consumer key/secret to use for signing. * - if an access token should be used for the request, and if so what it is. * * - the OAuth request/authorization/access URLs. * - what HTTP method to use for request token and access token requests * - where the OAuth parameters are located. * * Note that most of that work gets skipped for signed fetch, we just look up the consumer key * and secret for that. Signed fetch always sticks the parameters in the query string. */ public AccessorInfo getOAuthAccessor(ISecurityToken securityToken, OAuthArguments arguments, OAuthClientState clientState, OAuthResponseParams responseParams) { AccessorInfoBuilder accessorBuilder = new AccessorInfoBuilder(); // Does the gadget spec tell us any details about the service provider, like where to put the // OAuth parameters and what methods to use for their URLs? OAuthServiceProvider provider = null; if (arguments.mayUseToken()) { provider = lookupSpecInfo(securityToken, arguments, accessorBuilder, responseParams); } else { // This is plain old signed fetch. accessorBuilder.setParameterLocation(AccessorInfo.OAuthParamLocation.URI_QUERY); } // What consumer key/secret should we use? OAuthStore.ConsumerInfo consumer; try { consumer = store.getConsumerKeyAndSecret( securityToken, arguments.getServiceName(), provider); accessorBuilder.setConsumer(consumer); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Unable to retrieve consumer key", e); } // Should we use the OAuth access token? We never do this unless the client allows it, and // if owner == viewer. if (arguments.mayUseToken() && securityToken.getOwnerId() != null && securityToken.getViewerId().Equals(securityToken.getOwnerId())) { lookupToken(securityToken, consumer, arguments, clientState, accessorBuilder, responseParams); } return accessorBuilder.create(responseParams); }
public AccessorInfo create(OAuthResponseParams responseParams) { if (location == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no location"); } if (consumer == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no consumer"); } OAuthAccessor accessor = new OAuthAccessor(consumer.getConsumer()); // request token/access token/token secret can all be null, for signed fetch, or if the OAuth // dance is just beginning accessor.requestToken = requestToken; accessor.accessToken = accessToken; accessor.TokenSecret = tokenSecret; return new AccessorInfo(accessor, consumer, method, location, sessionHandle, tokenExpireMillis); }
public AccessorInfo create(OAuthResponseParams responseParams) { if (location == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no location"); } if (consumer == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no consumer"); } OAuthAccessor accessor = new OAuthAccessor(consumer.getConsumer()); // request token/access token/token secret can all be null, for signed fetch, or if the OAuth // dance is just beginning accessor.requestToken = requestToken; accessor.accessToken = accessToken; accessor.TokenSecret = tokenSecret; return(new AccessorInfo(accessor, consumer, method, location, sessionHandle, tokenExpireMillis)); }
/** * Remove an access token for the given user/gadget/service/token name */ public void removeToken(ISecurityToken securityToken, OAuthStore.ConsumerInfo consumerInfo, OAuthArguments arguments, OAuthResponseParams responseParams) { try { store.removeToken(securityToken, consumerInfo, arguments.getServiceName(), arguments.getTokenName()); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Unable to remove access token", e); } }
private GadgetSpec findSpec(ISecurityToken securityToken, OAuthArguments arguments, OAuthResponseParams responseParams) { try { return specFactory.getGadgetSpec(new Uri(securityToken.getAppUrl()), arguments.getBypassSpecCache()); } catch (UriFormatException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Could not fetch gadget spec, gadget URI invalid.", e); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Could not fetch gadget spec", e); } }
private static AccessorInfo.HttpMethod getStoreMethod(OAuthService.Method method, OAuthResponseParams responseParams) { if (method == OAuthService.Method.GET) { return AccessorInfo.HttpMethod.GET; } if (method == OAuthService.Method.POST) { return AccessorInfo.HttpMethod.POST; } throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "Unknown method " + method); }
private static AccessorInfo.OAuthParamLocation getStoreLocation(OAuthService.Location location, OAuthResponseParams responseParams) { if (location == OAuthService.Location.HEADER) { return AccessorInfo.OAuthParamLocation.AUTH_HEADER; } if (location == OAuthService.Location.URL) { return AccessorInfo.OAuthParamLocation.URI_QUERY; } if (location == OAuthService.Location.BODY) { return AccessorInfo.OAuthParamLocation.POST_BODY; } throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "Unknown parameter location " + location); }
/** * Figure out the OAuth token that should be used with this request. We check for this in three * places. In order of priority: * * 1) From information we cached on the client. * We encrypt the token and cache on the client for performance. * * 2) From information we have in our persistent state. * We persist the token server-side so we can look it up if necessary. * * 3) From information the gadget developer tells us to use (a preapproved request token.) * Gadgets can be initialized with preapproved request tokens. If the user tells the service * provider they want to add a gadget to a gadget container site, the service provider can * create a preapproved request token for that site and pass it to the gadget as a user * preference. * @throws GadgetException */ private void lookupToken(ISecurityToken securityToken, OAuthStore.ConsumerInfo consumerInfo, OAuthArguments arguments, OAuthClientState clientState, AccessorInfoBuilder accessorBuilder, OAuthResponseParams responseParams) { if (clientState.getRequestToken() != null) { // We cached the request token on the client. accessorBuilder.setRequestToken(clientState.getRequestToken()); accessorBuilder.setTokenSecret(clientState.getRequestTokenSecret()); } else if (clientState.getAccessToken() != null) { // We cached the access token on the client accessorBuilder.setAccessToken(clientState.getAccessToken()); accessorBuilder.setTokenSecret(clientState.getAccessTokenSecret()); accessorBuilder.setSessionHandle(clientState.getSessionHandle()); accessorBuilder.setTokenExpireMillis(clientState.getTokenExpireMillis()); } else { // No useful client-side state, check persistent storage OAuthStore.TokenInfo tokenInfo; try { tokenInfo = store.getTokenInfo(securityToken, consumerInfo, arguments.getServiceName(), arguments.getTokenName()); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Unable to retrieve access token", e); } if (tokenInfo != null && tokenInfo.getAccessToken() != null) { // We have an access token in persistent storage, use that. accessorBuilder.setAccessToken(tokenInfo.getAccessToken()); accessorBuilder.setTokenSecret(tokenInfo.getTokenSecret()); accessorBuilder.setSessionHandle(tokenInfo.getSessionHandle()); accessorBuilder.setTokenExpireMillis(tokenInfo.getTokenExpireMillis()); } else { // We don't have an access token yet, but the client sent us a (hopefully) preapproved // request token. accessorBuilder.setRequestToken(arguments.getRequestToken()); accessorBuilder.setTokenSecret(arguments.getRequestTokenSecret()); } } }
/** * Lookup information contained in the gadget spec. */ private OAuthServiceProvider lookupSpecInfo(ISecurityToken securityToken, OAuthArguments arguments, AccessorInfoBuilder accessorBuilder, OAuthResponseParams responseParams) { GadgetSpec spec = findSpec(securityToken, arguments, responseParams); OAuthSpec oauthSpec = spec.getModulePrefs().getOAuthSpec(); if (oauthSpec == null) { throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION, "Failed to retrieve OAuth URLs, spec for gadget " + securityToken.getAppUrl() + " does not contain OAuth element."); } OAuthService service = oauthSpec.getServices()[arguments.getServiceName()]; if (service == null) { throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION, "Failed to retrieve OAuth URLs, spec for gadget does not contain OAuth service " + arguments.getServiceName() + ". Known services: " + String.Join(",",oauthSpec.getServices().Keys.AsEnumerable().ToArray()) + '.'); } // In theory some one could specify different parameter locations for request token and // access token requests, but that's probably not useful. We just use the request token // rules for everything. accessorBuilder.setParameterLocation(getStoreLocation(service.getRequestUrl().location, responseParams)); accessorBuilder.setMethod(getStoreMethod(service.getRequestUrl().method, responseParams)); OAuthServiceProvider provider = new OAuthServiceProvider( service.getRequestUrl().url.ToString(), service.getAuthorizationUrl().ToString(), service.getAccessUrl().url.ToString()); return provider; }
/** * Retrieve an AccessorInfo and OAuthAccessor that are ready for signing OAuthMessages. To do * this, we need to figure out: * * - what consumer key/secret to use for signing. * - if an access token should be used for the request, and if so what it is. * * - the OAuth request/authorization/access URLs. * - what HTTP method to use for request token and access token requests * - where the OAuth parameters are located. * * Note that most of that work gets skipped for signed fetch, we just look up the consumer key * and secret for that. Signed fetch always sticks the parameters in the query string. */ public AccessorInfo getOAuthAccessor(ISecurityToken securityToken, OAuthArguments arguments, OAuthClientState clientState, OAuthResponseParams responseParams) { AccessorInfoBuilder accessorBuilder = new AccessorInfoBuilder(); // Does the gadget spec tell us any details about the service provider, like where to put the // OAuth parameters and what methods to use for their URLs? OAuthServiceProvider provider = null; if (arguments.mayUseToken()) { provider = lookupSpecInfo(securityToken, arguments, accessorBuilder, responseParams); } else { // This is plain old signed fetch. accessorBuilder.setParameterLocation(AccessorInfo.OAuthParamLocation.URI_QUERY); } // What consumer key/secret should we use? OAuthStore.ConsumerInfo consumer; try { consumer = store.getConsumerKeyAndSecret( securityToken, arguments.getServiceName(), provider); accessorBuilder.setConsumer(consumer); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Unable to retrieve consumer key", e); } // Should we use the OAuth access token? We never do this unless the client allows it, and // if owner == viewer. if (arguments.mayUseToken() && securityToken.getOwnerId() != null && securityToken.getViewerId().Equals(securityToken.getOwnerId())) { lookupToken(securityToken, consumer, arguments, clientState, accessorBuilder, responseParams); } return(accessorBuilder.create(responseParams)); }
private GadgetSpec findSpec(ISecurityToken securityToken, OAuthArguments arguments, OAuthResponseParams responseParams) { try { return(specFactory.getGadgetSpec(new Uri(securityToken.getAppUrl()), arguments.getBypassSpecCache())); } catch (UriFormatException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Could not fetch gadget spec, gadget URI invalid.", e); } catch (GadgetException e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Could not fetch gadget spec", e); } }
private static AccessorInfo.HttpMethod getStoreMethod(OAuthService.Method method, OAuthResponseParams responseParams) { if (method == OAuthService.Method.GET) { return(AccessorInfo.HttpMethod.GET); } if (method == OAuthService.Method.POST) { return(AccessorInfo.HttpMethod.POST); } throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "Unknown method " + method); }
private static AccessorInfo.OAuthParamLocation getStoreLocation(OAuthService.Location location, OAuthResponseParams responseParams) { if (location == OAuthService.Location.HEADER) { return(AccessorInfo.OAuthParamLocation.AUTH_HEADER); } if (location == OAuthService.Location.URL) { return(AccessorInfo.OAuthParamLocation.URI_QUERY); } if (location == OAuthService.Location.BODY) { return(AccessorInfo.OAuthParamLocation.POST_BODY); } throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "Unknown parameter location " + location); }
/** * OAuth authenticated fetch. */ public sResponse fetch(sRequest request) { realRequest = request; clientState = new OAuthClientState( fetcherConfig.getStateCrypter(), request.getOAuthArguments().getOrigClientState()); responseParams = new OAuthResponseParams(request.getSecurityToken(), request, fetcherConfig.getStateCrypter()); try { return fetchNoThrow(); } catch (Exception e) { // We log here to record the request/response pairs that created the failure. responseParams.logDetailedWarning("OAuth fetch unexpected fatal error", e); throw e; } }
/** * Lookup information contained in the gadget spec. */ private OAuthServiceProvider lookupSpecInfo(ISecurityToken securityToken, OAuthArguments arguments, AccessorInfoBuilder accessorBuilder, OAuthResponseParams responseParams) { GadgetSpec spec = findSpec(securityToken, arguments, responseParams); OAuthSpec oauthSpec = spec.getModulePrefs().getOAuthSpec(); if (oauthSpec == null) { throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION, "Failed to retrieve OAuth URLs, spec for gadget " + securityToken.getAppUrl() + " does not contain OAuth element."); } OAuthService service = oauthSpec.getServices()[arguments.getServiceName()]; if (service == null) { throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION, "Failed to retrieve OAuth URLs, spec for gadget does not contain OAuth service " + arguments.getServiceName() + ". Known services: " + String.Join(",", oauthSpec.getServices().Keys.AsEnumerable().ToArray()) + '.'); } // In theory some one could specify different parameter locations for request token and // access token requests, but that's probably not useful. We just use the request token // rules for everything. accessorBuilder.setParameterLocation(getStoreLocation(service.getRequestUrl().location, responseParams)); accessorBuilder.setMethod(getStoreMethod(service.getRequestUrl().method, responseParams)); OAuthServiceProvider provider = new OAuthServiceProvider( service.getRequestUrl().url.ToString(), service.getAuthorizationUrl().ToString(), service.getAccessUrl().url.ToString()); return(provider); }