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.google;
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 * Google User Service method definitions.
030 * 
031 * This class defines the APIs for registering a new account with the system and authentication using Google credentials, or more precisely, using the Google OAuth 2.0 authentication. The methods also describe the means for granting the system authorization for accessing content of the Google account.
032 * 
033 * Creating an account or authenticating with Google credentials does not automatically grant the system persistent permissions for accessing the account contents.
034 * 
035 * Note that the Google User Service does not contain a method for removing an existing user account. An existing account can be removed using the User Service 
036 */
037@HTTPService(name=Definitions.SERVICE_USERS_GOOGLE) 
038public class GoogleUserService {
039  
040  /**
041   * This method is called by Google after user has either denied or granted the service permission to his/her Google account, and is not meant to be used directly by the end-users. The method implements the OAuth2 authorization process as defined by Google.
042   * 
043   * @param authorizationCode OAuth2 authorization code generated by Google.
044   * @param errorCode Optional error message as reported by Google.
045   * @param nonce Short-lived nonce value randomly generated by the authorization process.
046   * @return response
047   */
048  @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_CALLBACK)
049  public Response oAuth2Callback(
050      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_AUTHORIZATION_CODE, required=false) StringParameter authorizationCode,
051      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ERROR_CODE, required=false) StringParameter errorCode,
052      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_STATE) StringParameter nonce
053      )
054  {
055    return GoogleUserCore.processOAuth2Callback(authorizationCode.getValue(), errorCode.getValue(), nonce.getValue());
056  }
057  
058  /**
059   * 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 Google account. 
060   * 
061   * 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.
062   * 
063   * @param authenticatedUser
064   * @return response
065   */
066  @HTTPServiceMethod(name=Definitions.METHOD_UNAUTHORIZE)
067  public Response unauthorize(
068      @HTTPAuthenticationParameter AuthenticationParameter authenticatedUser)
069  {
070    return GoogleUserCore.removeAuthorization(authenticatedUser.getUserIdentity());
071  }
072  
073  /**
074   * This method can be used to authenticate the user using Google credentials. The external account connection must be created either by registering the user as a new user using Google credentials or by authorizing the use of the Google account before the login functionality can be used.
075   * 
076   * The passed access token is used to validate the user identity. The token scope should contain at least <i>profile</i>. Additional Google OAuth2 scopes can be present, but are not required.
077   * 
078   * @param authenticatedUser
079   * @param accessToken OAuth2 access token as provided by Google.
080   * @return response
081   */
082  @HTTPServiceMethod(name=Definitions.METHOD_LOGIN)
083  public Response login(
084      @HTTPAuthenticationParameter(required=false) AuthenticationParameter authenticatedUser,
085      @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken
086      )
087  {
088    if(UserIdentity.isValid(authenticatedUser.getUserIdentity())){
089      return new Response(Status.BAD_REQUEST, "Already logged in. Please logout first.");
090    }
091    return GoogleUserCore.login(authenticatedUser.getSession(), accessToken.getValue());
092  }
093  
094  /**
095   * This method can be used to register a new user using a Google account. The passed access token is used to retrieve the required registration details from the account. The token scope should contain at least profile, additional Google OAuth2 scopes can be present, but are not required.
096   * 
097   * The Google account is assumed to be personal, and an attempt to use the same account to create multiple accounts will result in an error.
098   * 
099   * @param accessToken OAuth2 access token as provided by Google.
100   * @return response
101   */
102  @HTTPServiceMethod(name=service.tut.pori.users.Definitions.METHOD_REGISTER)
103  public Response register(@HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken)
104  {
105    return GoogleUserCore.register(accessToken.getValue());
106  }
107  
108  /**
109   * This method can be used to grant the service access to the authenticated user's Google account. This method will redirect to Google's consent page asking user's permission to access the account. The default configuration will ask permissions for <i>https://picasaweb.google.com/data/</i> and <i>profile</i> Google OAuth2 scopes, though the actual scopes required will depend on the services to be used.
110   * 
111   * The authorization process will use the default OAuth2 authentication flow as implemented by Google, 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 show status message notifying the result of the authorization.
112   * 
113   * The method assumes that Google accounts are personal and an attempt to authorize the same Google account for multiple users will result in error.
114   * 
115   * @param authenticatedUser
116   * @return response
117   */
118  @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_AUTHORIZATION_REDIRECT)
119  public Response authorize(@HTTPAuthenticationParameter AuthenticationParameter authenticatedUser){
120    return GoogleUserCore.createAuthorizationRedirection(authenticatedUser.getUserIdentity());
121  }
122}