com.sangupta.satya.client.BaseAuthClient Maven / Gradle / Ivy
/**
*
* satya - social authentication framework
* Copyright (c) 2014, Sandeep Gupta
*
* http://sangupta.com/projects/satya
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sangupta.satya.client;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.FieldNamingPolicy;
import com.sangupta.jerry.http.WebInvoker;
import com.sangupta.jerry.http.WebRequest;
import com.sangupta.jerry.http.WebRequestMethod;
import com.sangupta.jerry.http.WebResponse;
import com.sangupta.jerry.oauth.domain.KeySecretPair;
import com.sangupta.jerry.oauth.domain.TokenAndUrl;
import com.sangupta.jerry.oauth.extractor.TokenExtractor;
import com.sangupta.jerry.oauth.service.OAuth1ServiceImpl;
import com.sangupta.jerry.oauth.service.OAuth2ServiceImpl;
import com.sangupta.jerry.oauth.service.OAuthService;
import com.sangupta.jerry.util.AssertUtils;
import com.sangupta.jerry.util.GsonUtils;
import com.sangupta.satya.AuthProvider;
import com.sangupta.satya.AuthenticatedUser;
import com.sangupta.satya.SatyaUtils;
/**
* Abtsract implementation of the {@link AuthClient} that provides most of the
* common functionality.
*
* @author sangupta
* @since 1.0
*/
public abstract class BaseAuthClient implements AuthClient {
/**
* My logger instance
*/
private static final Logger LOGGER = LoggerFactory.getLogger(BaseAuthClient.class);
/**
* The {@link OAuthService} to use
*
*/
protected final OAuthService service;
/**
* The scopes to use when requesting permissions
*/
protected final String defaultScopes;
/**
* Constructor that takes in the final {@link OAuthService} to use and the
* scopes that we need to interact with.
*
* @param service
* the {@link OAuthService} to be used
*
* @param scope
* the default scopes for this client
*/
public BaseAuthClient(OAuthService service, String scope) {
if(service == null) {
throw new IllegalArgumentException("OAuthService to be used cannot be null");
}
this.service = service;
this.defaultScopes = scope;
}
/**
* Constructor that takes in the final {@link OAuthService} to use and the
* scopes that we need to interact with.
*
* @param service
* the {@link OAuthService} to be used
*
* @param scopes
* the list of all default scopes for this client
*/
public BaseAuthClient(OAuthService service, String... scopes) {
if(service == null) {
throw new IllegalArgumentException("OAuthService to be used cannot be null");
}
this.service = service;
this.defaultScopes = SatyaUtils.merge(scopes, getScopeMergingCharacter());
}
/**
* @see AuthClient#getLoginRedirectURL(String)
*/
@Override
public TokenAndUrl getLoginRedirectURL(String successUrl) {
return this.service.getLoginURL(successUrl, this.defaultScopes);
}
/**
* @see com.sangupta.satya.client.AuthClient#getLoginRedirectURL(java.lang.String, java.lang.String)
*/
@Override
public TokenAndUrl getLoginRedirectURL(String successUrl, String scope) {
return this.service.getLoginURL(successUrl, scope);
}
/**
* @see com.sangupta.satya.client.AuthClient#getLoginRedirectURL(java.lang.String, java.lang.String[])
*/
@Override
public TokenAndUrl getLoginRedirectURL(String successUrl, String... scopes) {
return this.service.getLoginURL(successUrl, SatyaUtils.merge(scopes, this.getScopeMergingCharacter()));
}
/**
* Indicate the {@link AuthProvider} that we handle.
*
* @return
*/
protected abstract AuthProvider getAuthProvider();
/**
* Return the character that needs to be used to merge different scopes
*
* @return
*/
protected char getScopeMergingCharacter() {
return ',';
}
/**
* Return the {@link OAuthService} being used.
*
*/
public OAuthService getOAuthService() {
return this.service;
}
/**
* Verify the incoming user.
*
*/
@Override
public AuthenticatedUser verifyUser(HttpServletRequest request, final TokenAndUrl tokenAndUrl) {
// extract the code from the request parameter
String errorCode = request.getParameter("error");
if(AssertUtils.isNotEmpty(errorCode)) {
// TODO: make checked exceptions so that user's know what's happening
return null;
}
errorCode = request.getParameter("error_code");
if(AssertUtils.isNotEmpty(errorCode)) {
// TODO: make checked exceptions so that user's know what's happening
return null;
}
// find the actual code
String code = request.getParameter(this.service.getVerificationCodeParamName());
return this.verifyUser(code, tokenAndUrl);
}
/**
*
* @return
*/
protected abstract TokenExtractor getTokenExtractor();
protected abstract AuthenticatedUser createNewAuthenticatedUser(Map rawParameters);
@Override
public AuthenticatedUser verifyUser(String verifier, TokenAndUrl tokenAndUrl) {
if(this.service instanceof OAuth2ServiceImpl) {
return verifyUserOAuth2(tokenAndUrl, verifier);
}
if(this.service instanceof OAuth1ServiceImpl) {
return verifyUserOAuth1(tokenAndUrl, verifier);
}
throw new IllegalStateException("Don't know how to handle the verification of user");
}
protected AuthenticatedUser verifyUserOAuth1(TokenAndUrl tokenAndUrl, String verifier) {
if(AssertUtils.isEmpty(verifier)) {
throw new IllegalArgumentException("The request does not appear to be a valid " + getAuthProvider() + " request");
}
// obtain the authorization code
String response = this.service.getAuthorizationResponse(tokenAndUrl, verifier);
if(AssertUtils.isEmpty(response)) {
return null;
}
Map map = getTokenExtractor().extractTokens(response);
return createNewAuthenticatedUser(map);
}
/**
*
* @param verifier
* @param redirectURL
* @return
*/
protected AuthenticatedUser verifyUserOAuth2(TokenAndUrl tokenAndUrl, String verifier) {
if(AssertUtils.isEmpty(verifier)) {
throw new IllegalArgumentException("The request does not appear to be a valid " + getAuthProvider() + " request");
}
System.out.println("Using " + getAuthProvider() + " verification code: " + verifier);
// obtain the authorization code
String response = this.service.getAuthorizationResponse(tokenAndUrl, verifier);
if(AssertUtils.isEmpty(response)) {
return null;
}
Map map = getTokenExtractor().extractTokens(response);
return createNewAuthenticatedUser(map);
}
/**
* The field naming policy to be used when parsing responses from JSON.
*
* @return
*/
protected FieldNamingPolicy getFieldNamingPolicy() {
return FieldNamingPolicy.IDENTITY;
}
/**
* @see AuthClient#signOut()
*/
@Override
public boolean signOut() {
return false;
}
/**
* @see AuthClient#getUsingJson(KeySecretPair, String, Class)
*/
@Override
public T getUsingJson(KeySecretPair accessPair, String url, Class clazz) {
url = this.service.signRequestUrl(url, accessPair);
LOGGER.debug("Hitting signed URL: {}", url);
WebRequest request = WebInvoker.getWebRequest(url, WebRequestMethod.GET);
this.service.signRequest(request, accessPair);
WebResponse response = WebInvoker.executeSilently(request);
if(response == null) {
LOGGER.error("Null response from url: {}", url);
return null;
}
if(!response.isSuccess()) {
LOGGER.error("Invalid response from url: {} with response: {}", url, response.trace());
LOGGER.error(response.getContent());
return null;
}
String content = response.getContent();
LOGGER.debug("Webresponse: " + content);
return GsonUtils.getGson(getFieldNamingPolicy()).fromJson(content, clazz);
}
/**
* @see AuthClient#signRequest(KeySecretPair, WebRequest)
*/
@Override
public void signRequest(KeySecretPair accessPair, WebRequest request) {
this.service.signRequest(request, accessPair);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy