/*******************************************************************************
* Copyright (c) 2014 IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.authentication.oauth.google;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.eclipse.orion.server.authentication.oauth.OAuthConsumer;
import org.eclipse.orion.server.authentication.oauth.OAuthException;
import org.eclipse.orion.server.core.resources.Base64;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Google specific OAuthConsumer used to handle google oauth token responses.
* @author Aidan Redpath
*
*/
public class GoogleOAuthConsumer extends OAuthConsumer {
// Parameters
private static final String TOKEN_PARAMETER = "id_token";
private static final String ID_PARAMETER = "sub";
private static final String PROVIDER_PARAMETER = "iss";
private static final String EMAIL_PARAMETER = "email";
private static final String EMAIL_VERIFIED_PARAMETER = "email_verified";
private static final String OPEN_ID_PARAMETER = "openid_id";
private String userId;
private String provider;
private String openid_id;
private String email;
private boolean email_verified;
public GoogleOAuthConsumer(OAuthAccessTokenResponse oauthAccessTokenResponse, String redirect) throws OAuthException {
super(oauthAccessTokenResponse, redirect);
try {
JSONObject json = new JSONObject(oauthAccessTokenResponse.getBody());
String jwt = json.getString(TOKEN_PARAMETER);
parseToken(jwt);
} catch (JSONException e) {
throw new OAuthException(e);
}
}
private void parseToken(String jwt) throws OAuthException {
String [] sections = jwt.split("\\.");
if(sections.length != 3)
throw new OAuthException("An error occured while authenticating");
// No validation required since the token comes directly from the google server
// JWT Structure
// Header.Claim.Signature
String claim = sections[1];
int buffer = 4 - (claim.length() % 4);
// Encoded base64 should never need 3 buffer characters
if(buffer == 3)
throw new OAuthException("An error occured while authenticating");
// Don't add 4 buffer characters
for(int i = 0; i < buffer && buffer != 4; i++) {
claim += "=";
}
String decodedClaim = new String(Base64.decode(claim.getBytes()));
JSONObject jsonClaim;
try {
jsonClaim = new JSONObject(decodedClaim);
userId = jsonClaim.getString(ID_PARAMETER);
provider = jsonClaim.getString(PROVIDER_PARAMETER);
openid_id = jsonClaim.optString(OPEN_ID_PARAMETER, null);
} catch (JSONException e) {
throw new OAuthException(e);
}
email = "";
email_verified = false;
try{
email = jsonClaim.getString(EMAIL_PARAMETER);
email_verified = jsonClaim.getBoolean(EMAIL_VERIFIED_PARAMETER);
} catch (JSONException e) {
// Suppress
}
}
/**
* Gets a unique identifier for the user.
*/
@Override
public String getIdentifier() {
return provider + "/" + userId;
}
public String getOpenidIdentifier(){
return openid_id;
}
/**
* Gets the user's email.
*/
@Override
public String getEmail() {
return email;
}
/**
* Gets a username to user for Orion.
*/
@Override
public String getUsername() {
return getEmail() == null ? null : getEmail().split("@")[0];
}
public boolean isEmailVerifiecd() {
return email_verified;
}
}