001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.users.facebook;
017
018import core.tut.pori.http.Response;
019import core.tut.pori.http.Response.Status;
020import core.tut.pori.http.annotations.HTTPAuthenticationParameter;
021import core.tut.pori.http.annotations.HTTPMethodParameter;
022import core.tut.pori.http.annotations.HTTPService;
023import core.tut.pori.http.annotations.HTTPServiceMethod;
024import core.tut.pori.http.parameters.AuthenticationParameter;
025import core.tut.pori.http.parameters.StringParameter;
026import core.tut.pori.users.UserIdentity;
027
028/**
029 * Facebook User Service method definitions.
030 * 
031 * This class defines the APIs for registering a new account with the system and authentication using Facebook credentials, or more precisely, using the Facebook OAuth 2.0 authentication. The methods also describe the means for granting the system authorization for accessing content of the Facebook account.
032 * Creating an account or authenticating with Facebook credentials does not automatically grant the system persistent permissions for accessing the account contents.
033 * 
034 * Note that the Facebook User Service does not contain a method for removing an existing user account. An existing account can be removed using the User Service.
035 * 
036 */
037@HTTPService(name=Definitions.SERVICE_USERS_FACEBOOK) 
038public class FacebookUserService {
039  /**
040   * This method is called by Facebook after user has either denied or granted the service permission to his/her Facebook account, and is not meant to be used directly by the end-users. The method implements the OAuth2 authorization process as defined by Facebook.
041   * 
042   * @param authorizationCode OAuth2 authorization code generated by Facebook.
043   * @param errorCode Optional error message as reported by Facebook.
044   * @param nonce Short-lived nonce value randomly generated by the authorization process.
045   * @return response
046   */
047  @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_CALLBACK)
048  public Response oAuth2Callback(
049      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_AUTHORIZATION_CODE, required=false) StringParameter authorizationCode,
050      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ERROR_CODE, required=false) StringParameter errorCode,
051      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_STATE) StringParameter nonce
052      )
053  {
054    return FacebookUserCore.processOAuth2Callback(authorizationCode.getValue(), errorCode.getValue(), nonce.getValue());
055  }
056  
057  /**
058   * This method can be used to authenticate the user using Facebook credentials. The external account connection must be created either by registering the user as a new user using Facebook credentials or by authorizing the use of the Facebook account before the login functionality can be used.
059   * 
060   * The passed access token is used to validate the user identity. The token scope should contain at least <i>public_profile</i>, which should be present in each token by default. Additional Facebook OAuth2 scopes can be present, but are not required.
061   * 
062   * @param authenticatedUser
063   * @param accessToken OAuth2 access token as provided by Facebook.
064   * @return response
065   */
066  @HTTPServiceMethod(name=Definitions.METHOD_LOGIN)
067  public Response login(
068      @HTTPAuthenticationParameter(required=false) AuthenticationParameter authenticatedUser,
069      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken
070      )
071  {
072    if(UserIdentity.isValid(authenticatedUser.getUserIdentity())){
073      return new Response(Status.BAD_REQUEST, "Already logged in. Please logout first.");
074    }
075    return FacebookUserCore.login(authenticatedUser.getSession(), accessToken.getValue());
076  }
077  
078  /**
079   * This method can be used to register a new user using a Facebook account. The passed access token is used to retrieve the required registration details from the account. The token scope should contain at least public_profile, which should be present in each token by default. Additional Facebook OAuth2 scopes can be present, but are not required.
080   * 
081   * The Facebook account is assumed to be personal, and an attempt to use the same account to create multiple accounts will result in an error.
082   * 
083   * @param accessToken OAuth2 access token as provided by Facebook
084   * @return response
085   */
086  @HTTPServiceMethod(name=service.tut.pori.users.Definitions.METHOD_REGISTER)
087  public Response register(@HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken)
088  {
089    return FacebookUserCore.register(accessToken.getValue());
090  }
091  
092  /**
093   * This method can be used to grant the service access to the authenticated user's Facebook account. This method will redirect to Facebook's consent page asking user's permission to access the account. The default configuration will ask permissions for all Facebook OAuth2 scopes, though the actual scopes required will depend on the services to be used.
094   * 
095   * The authorization process will use the default OAuth2 authentication flow as implemented by Facebook, firstly redirecting the user to the consent page, which in turn will redirect the user back to the OAuth2 callback method. The callback method will either show status message notifying the result of the authorization process or redirect to final target, if redirection URL was provided.
096   * 
097   * The method assumes that Facebook accounts are personal and an attempt to authorize the same Facebook account for multiple users will result in error.
098   * 
099   * @param authenticatedUser
100   * @param redirectUri The final target, where the user should be redirected to after successful authorization. If not given, a default status message will be shown.
101   * @return Error response, redirection or default OK response depending on the given parameters.
102   */
103  @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_AUTHORIZATION_REDIRECT)
104  public Response authorize(
105      @HTTPAuthenticationParameter AuthenticationParameter authenticatedUser,
106      @HTTPMethodParameter(name=Definitions.PARAMETER_FACEBOOK_HACK_REDIRECT_URI, required=false) StringParameter redirectUri){
107    return FacebookUserCore.createAuthorizationRedirection(authenticatedUser.getUserIdentity(), redirectUri.getValue());
108  }
109  
110  /**
111   * This method allows a user to revoke the previously given authorization permissions. Note that calling this method does not prevent user from authenticating (logging in) using the credentials, nor will it remove the user account from the system, but calling this method will prevent the system from accessing the user's content stored in the Facebook account. 
112   * 
113   * In practice this means, that no synchronization can be performed for the account until authorization is restored. <i>All</i> previously synchronized content will be removed from the system.
114   * 
115   * @param authenticatedUser
116   * @return response
117   */
118  @HTTPServiceMethod(name=Definitions.METHOD_UNAUTHORIZE)
119  public Response unauthorize(
120      @HTTPAuthenticationParameter AuthenticationParameter authenticatedUser)
121  {
122    return FacebookUserCore.removeAuthorization(authenticatedUser.getUserIdentity());
123  }
124}