/* * JBoss, a division of Red Hat * Copyright 2013, Red Hat Middleware, LLC, and individual * contributors as indicated by the @authors tag. See the * copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.gatein.security.oauth.spi; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.exoplatform.services.organization.UserProfile; import org.gatein.security.oauth.exception.OAuthException; /** * Processor to call operations on given OAuth provider (Social network) * * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> */ public interface OAuthProviderProcessor<T extends AccessTokenContext> { /** * Process OAuth workflow for this OAuth provider (social network). Workflow is finished if returned {@link org.gatein.security.oauth.spi.InteractionState} * is in state {@link org.gatein.security.oauth.spi.InteractionState.State#FINISH} and in this case, InteractionState should also have accessToken filled. * * If {@link org.gatein.security.oauth.spi.InteractionState} is in state {@link org.gatein.security.oauth.spi.InteractionState.State#AUTH}, then more redirections are needed. In this case, * given {@link HttpServletResponse} should be already committed and prepared for redirection. * * @param httpRequest * @param httpResponse * @return InteractionState with state of OAuth interaction * @throws IOException if IO error occured (for example if httpResponse.sendRedirect failed) * @throws OAuthException in case of some other error, which may be specific for this OAuth processor (Details are available in error code) * Caller should be able to handle at least {@link org.gatein.security.oauth.exception.OAuthExceptionCode#USER_DENIED_SCOPE} * which happens when user denied scope (authorization screen in web of given social network) */ InteractionState<T> processOAuthInteraction(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, OAuthException; /** * Possibility to create new OAuth interaction with custom scope (not just the scope which is provided in configuration of this OAuth processor) * @see {@link #processOAuthInteraction(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} * * @param httpRequest * @param httpResponse * @param scope custom scope, which contains all scopes in single String divided by {@link AccessTokenContext#DELIMITER} * @return * @throws IOException * @throws OAuthException */ InteractionState<T> processOAuthInteraction(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String scope) throws IOException, OAuthException; /** * Revoke given access token on OAuth provider side, so application is removed from list of supported applications for given user * * @param accessToken access token to revoke * @throws OAuthException with code {@link org.gatein.security.oauth.exception.OAuthExceptionCode#TOKEN_REVOCATION_FAILED} * if remote revocation of access token failed for some reason */ void revokeToken(T accessToken) throws OAuthException; /** * Send request to OAuth Provider to validate if given access token is valid and ask for scopes, which are available for given accessToken. * Returned access token should be always valid and prepared for invoke other operations * * @param accessToken accessToken which will be used to ask OAuthProvider about validation and for available scopes * @return accessTokenContext, which will be quite same as the one from accessToken parameter. It could have some info updated (like scopes) * @throws OAuthException usually with codes: * - {@link org.gatein.security.oauth.exception.OAuthExceptionCode#ACCESS_TOKEN_ERROR} if invalid access is used as argument * - {@link org.gatein.security.oauth.exception.OAuthExceptionCode#IO_ERROR} if IO error occurs */ T validateTokenAndUpdateScopes(T accessToken) throws OAuthException; /** * Return object, which can be used to call some operations on this Social network. For example "Plus" object for Google+ network * * @param socialApiObjectType Type of object, which we wanted to return. Method will return null if this type is not supported by this processor * @param accessToken access token used to initialize object * @return initialized object of required type or null if type wasn't found (supported) by this processor */ <C> C getAuthorizedSocialApiObject(T accessToken, Class<C> socialApiObjectType); // OPERATIONS FOR ACCESS TOKEN PERSISTENCE /** * Save accessToken data to given userProfile. Note that we are not calling any DB save operations, just filling data into * given userProfile * * @param userProfile where data about access token will be filled * @param codec to encode some attributes (sensitive data) before save them to user profile * @param accessToken specific access token for this OAuth processor */ void saveAccessTokenAttributesToUserProfile(UserProfile userProfile, OAuthCodec codec, T accessToken); /** * Obtain needed data from given userProfile and create accessToken from them * * @param userProfile where data from access token will be obtained * @param codec to decode data from userProfile * @return accesstoken or null if accessToken is not found in persistent storage */ T getAccessTokenFromUserProfile(UserProfile userProfile, OAuthCodec codec); /** * Remove data about access token from this user profile * @param userProfile from which data will be removed */ void removeAccessTokenFromUserProfile(UserProfile userProfile); }