diff options
Diffstat (limited to 'src/com/p4square/f1oauth')
-rw-r--r-- | src/com/p4square/f1oauth/F1OAuthHelper.java | 128 | ||||
-rw-r--r-- | src/com/p4square/f1oauth/SecondPartyAuthenticator.java | 52 | ||||
-rw-r--r-- | src/com/p4square/f1oauth/SecondPartyVerifier.java | 60 |
3 files changed, 240 insertions, 0 deletions
diff --git a/src/com/p4square/f1oauth/F1OAuthHelper.java b/src/com/p4square/f1oauth/F1OAuthHelper.java new file mode 100644 index 0000000..d75460f --- /dev/null +++ b/src/com/p4square/f1oauth/F1OAuthHelper.java @@ -0,0 +1,128 @@ +/* + * Copyright 2013 Jesse Morgan + */ + +package com.p4square.f1oauth; + +import java.net.URLEncoder; + +import org.apache.log4j.Logger; + +import org.restlet.Context; +import org.restlet.Response; +import org.restlet.Request; +import org.restlet.data.ChallengeResponse; +import org.restlet.data.ChallengeScheme; +import org.restlet.data.Method; +import org.restlet.engine.util.Base64; +import org.restlet.representation.StringRepresentation; + +import com.p4square.restlet.oauth.OAuthException; +import com.p4square.restlet.oauth.OAuthHelper; +import com.p4square.restlet.oauth.OAuthUser; +import com.p4square.restlet.oauth.Token; + +/** + * + * @author Jesse Morgan <jesse@jesterpm.net> + */ +public class F1OAuthHelper extends OAuthHelper { + public enum UserType { + WEBLINK, PORTAL; + } + + private static final Logger LOG = Logger.getLogger(F1OAuthHelper.class); + + private static final String VERSION_STRING = "/v1/"; + private static final String REQUESTTOKEN_URL = "Tokens/RequestToken"; + private static final String AUTHORIZATION_URL = "Login"; + private static final String ACCESSTOKEN_URL= "Tokens/AccessToken"; + private static final String TRUSTED_ACCESSTOKEN_URL = "/AccessToken"; + + private final String mBaseUrl; + private final String mMethod; + + /** + * @param method Either WeblinkUser or PortalUser. + */ + public F1OAuthHelper(Context context, String consumerKey, String consumerSecret, + String baseUrl, String churchCode, UserType userType) { + super(context, consumerKey, consumerSecret); + + switch (userType) { + case WEBLINK: + mMethod = "WeblinkUser"; + break; + case PORTAL: + mMethod = "PortalUser"; + break; + default: + throw new IllegalArgumentException("Unknown UserType"); + } + + mBaseUrl = "https://" + churchCode + "." + baseUrl + VERSION_STRING; + } + + /** + * @return the URL for the initial RequestToken request. + */ + protected String getRequestTokenUrl() { + return mBaseUrl + REQUESTTOKEN_URL; + } + + /** + * @return the URL to redirect the user to for Authentication. + */ + public String getLoginUrl(Token requestToken, String callback) { + String loginUrl = mBaseUrl + mMethod + AUTHORIZATION_URL + + "?oauth_token=" + URLEncoder.encode(requestToken.getToken()); + + if (callback != null) { + loginUrl += "&oauth_callback=" + URLEncoder.encode(callback); + } + + return loginUrl; + } + + + /** + * @return the URL for the AccessToken request. + */ + protected String getAccessTokenUrl() { + return mBaseUrl + ACCESSTOKEN_URL; + } + + /** + * Request an AccessToken for a particular username and password. + * + * This is an F1 extension to OAuth: + * http://developer.fellowshipone.com/docs/v1/Util/AuthDocs.help#2creds + */ + public OAuthUser getAccessToken(String username, String password) throws OAuthException { + Request request = new Request(Method.POST, mBaseUrl + mMethod + TRUSTED_ACCESSTOKEN_URL); + request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH)); + + String base64String = Base64.encode((username + " " + password).getBytes(), false); + request.setEntity(new StringRepresentation(base64String)); + + return processAccessTokenRequest(request); + } + + public void createAccount(String firstname, String lastname, String email, String redirect) + throws OAuthException { + String req = String.format("{\n\"account\":{\n\"firstName\":\"%s\",\n" + + "\"lastName\":\"%s\",\n\"email\":\"%s\",\n" + + "\"urlRedirect\":\"%s\"\n}\n}", + firstname, lastname, email, redirect); + + Request request = new Request(Method.POST, mBaseUrl + "/Accounts"); + request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH)); + request.setEntity(new StringRepresentation(req)); + + Response response = getResponse(request); + + if (!response.getStatus().isSuccess()) { + throw new OAuthException(response.getStatus()); + } + } +} diff --git a/src/com/p4square/f1oauth/SecondPartyAuthenticator.java b/src/com/p4square/f1oauth/SecondPartyAuthenticator.java new file mode 100644 index 0000000..1983d69 --- /dev/null +++ b/src/com/p4square/f1oauth/SecondPartyAuthenticator.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Jesse Morgan + */ + +package com.p4square.f1oauth; + +import org.apache.log4j.Logger; + +import com.p4square.restlet.oauth.OAuthException; +import com.p4square.restlet.oauth.OAuthUser; + +import org.restlet.Context; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.security.Authenticator; + +/** + * Restlet Authenticator for 2nd + * @author Jesse Morgan <jesse@jesterpm.net> + */ +public class SecondPartyAuthenticator extends Authenticator { + private static final Logger LOG = Logger.getLogger(SecondPartyAuthenticator.class); + + private final F1OAuthHelper mHelper; + + public SecondPartyAuthenticator(Context context, boolean optional, F1OAuthHelper helper) { + super(context, optional); + + mHelper = helper; + } + + protected boolean authenticate(Request request, Response response) { + if (request.getChallengeResponse() == null) { + return false; // no credentials + } + + String username = request.getChallengeResponse().getIdentifier(); + String password = new String(request.getChallengeResponse().getSecret()); + + try { + OAuthUser user = mHelper.getAccessToken(username, password); + request.getClientInfo().setUser(user); + + return true; + + } catch (OAuthException e) { + LOG.info("OAuth Exception: " + e); + } + + return false; // Invalid credentials + } +} diff --git a/src/com/p4square/f1oauth/SecondPartyVerifier.java b/src/com/p4square/f1oauth/SecondPartyVerifier.java new file mode 100644 index 0000000..870fe3e --- /dev/null +++ b/src/com/p4square/f1oauth/SecondPartyVerifier.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013 Jesse Morgan + */ + +package com.p4square.f1oauth; + +import org.apache.log4j.Logger; + +import com.p4square.restlet.oauth.OAuthException; +import com.p4square.restlet.oauth.OAuthUser; + +import org.restlet.Context; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.security.Verifier; + +/** + * Restlet Verifier for F1 2nd Party Authentication + * + * @author Jesse Morgan <jesse@jesterpm.net> + */ +public class SecondPartyVerifier implements Verifier { + private static final Logger LOG = Logger.getLogger(SecondPartyVerifier.class); + + private final F1OAuthHelper mHelper; + + public SecondPartyVerifier(F1OAuthHelper helper) { + if (helper == null) { + throw new IllegalArgumentException("Helper can not be null."); + } + + mHelper = helper; + } + + @Override + public int verify(Request request, Response response) { + if (request.getChallengeResponse() == null) { + return RESULT_MISSING; // no credentials + } + + String username = request.getChallengeResponse().getIdentifier(); + String password = new String(request.getChallengeResponse().getSecret()); + + try { + OAuthUser user = mHelper.getAccessToken(username, password); + user.setIdentifier(username); + user.setEmail(username); + + // This seems like a hack... but it'll work + request.getClientInfo().setUser(user); + + return RESULT_VALID; + + } catch (OAuthException e) { + LOG.info("OAuth Exception: " + e, e); + } + + return RESULT_INVALID; // Invalid credentials + } +} |