diff options
Diffstat (limited to 'src/com/p4square/grow/ccb')
-rw-r--r-- | src/com/p4square/grow/ccb/CCBUser.java | 37 | ||||
-rw-r--r-- | src/com/p4square/grow/ccb/CCBUserVerifier.java | 50 | ||||
-rw-r--r-- | src/com/p4square/grow/ccb/ChurchCommunityBuilderIntegrationDriver.java | 50 | ||||
-rw-r--r-- | src/com/p4square/grow/ccb/MonitoredCCBAPI.java | 68 |
4 files changed, 205 insertions, 0 deletions
diff --git a/src/com/p4square/grow/ccb/CCBUser.java b/src/com/p4square/grow/ccb/CCBUser.java new file mode 100644 index 0000000..7313172 --- /dev/null +++ b/src/com/p4square/grow/ccb/CCBUser.java @@ -0,0 +1,37 @@ +package com.p4square.grow.ccb; + +import com.p4square.ccbapi.model.IndividualProfile; +import org.restlet.security.User; + +/** + * CCBUser is an adapter between a CCB IndividualProfile and a Restlet User. + * + * Note: CCBUser prefixes the user's identifier with "CCB-". This is done to + * ensure the identifier does not collide with identifiers from other + * systems. + */ +public class CCBUser extends User { + + private final IndividualProfile mProfile; + + /** + * Wrap an IndividualProfile inside a User object. + * + * @param profile The CCB IndividualProfile for the user. + */ + public CCBUser(final IndividualProfile profile) { + mProfile = profile; + + setIdentifier("CCB-" + mProfile.getId()); + setFirstName(mProfile.getFirstName()); + setLastName(mProfile.getLastName()); + setEmail(mProfile.getEmail()); + } + + /** + * @return The IndividualProfile of the user. + */ + public IndividualProfile getProfile() { + return mProfile; + } +} diff --git a/src/com/p4square/grow/ccb/CCBUserVerifier.java b/src/com/p4square/grow/ccb/CCBUserVerifier.java new file mode 100644 index 0000000..db10b75 --- /dev/null +++ b/src/com/p4square/grow/ccb/CCBUserVerifier.java @@ -0,0 +1,50 @@ +package com.p4square.grow.ccb; + +import com.p4square.ccbapi.CCBAPI; +import com.p4square.ccbapi.model.GetIndividualProfilesRequest; +import com.p4square.ccbapi.model.GetIndividualProfilesResponse; +import org.apache.log4j.Logger; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.security.Verifier; + +/** + * CCBUserVerifier authenticates a user through the CCB individual_profile_from_login_password API. + */ +public class CCBUserVerifier implements Verifier { + private static final Logger LOG = Logger.getLogger(CCBUserVerifier.class); + + private final CCBAPI mAPI; + + public CCBUserVerifier(final CCBAPI api) { + mAPI = api; + } + + @Override + public int verify(Request request, Response response) { + if (request.getChallengeResponse() == null) { + return RESULT_MISSING; // no credentials + } + + final String username = request.getChallengeResponse().getIdentifier(); + final char[] password = request.getChallengeResponse().getSecret(); + + try { + GetIndividualProfilesResponse resp = mAPI.getIndividualProfiles( + new GetIndividualProfilesRequest().withLoginPassword(username, password)); + + if (resp.getIndividuals().size() == 1) { + // Wrap the IndividualProfile up in an User and update the user on the request. + final CCBUser user = new CCBUser(resp.getIndividuals().get(0)); + LOG.info("Successfully authenticated " + user.getIdentifier()); + request.getClientInfo().setUser(user); + return RESULT_VALID; + } + + } catch (Exception e) { + LOG.error("CCB API Exception: " + e, e); + } + + return RESULT_INVALID; // Invalid credentials + } +} diff --git a/src/com/p4square/grow/ccb/ChurchCommunityBuilderIntegrationDriver.java b/src/com/p4square/grow/ccb/ChurchCommunityBuilderIntegrationDriver.java new file mode 100644 index 0000000..3aeca2c --- /dev/null +++ b/src/com/p4square/grow/ccb/ChurchCommunityBuilderIntegrationDriver.java @@ -0,0 +1,50 @@ +package com.p4square.grow.ccb; + +import com.codahale.metrics.MetricRegistry; +import com.p4square.ccbapi.CCBAPI; +import com.p4square.ccbapi.CCBAPIClient; +import com.p4square.grow.config.Config; +import com.p4square.grow.frontend.IntegrationDriver; +import org.restlet.Context; +import org.restlet.security.Verifier; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * The ChurchCommunityBuilderIntegrationDriver is used to integrate Grow with Church Community Builder. + */ +public class ChurchCommunityBuilderIntegrationDriver implements IntegrationDriver { + + private final Context mContext; + private final MetricRegistry mMetricRegistry; + private final Config mConfig; + + private final CCBAPI mAPI; + + public ChurchCommunityBuilderIntegrationDriver(final Context context) { + mContext = context; + mConfig = (Config) context.getAttributes().get("com.p4square.grow.config"); + mMetricRegistry = (MetricRegistry) context.getAttributes().get("com.p4square.grow.metrics"); + + try { + CCBAPI api = new CCBAPIClient(new URI(mConfig.getString("CCBAPIURL", "")), + mConfig.getString("CCBAPIUser", ""), + mConfig.getString("CCBAPIPassword", "")); + + if (mMetricRegistry != null) { + api = new MonitoredCCBAPI(api, mMetricRegistry); + } + + mAPI = api; + + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Override + public Verifier newUserAuthenticationVerifier() { + return new CCBUserVerifier(mAPI); + } +} diff --git a/src/com/p4square/grow/ccb/MonitoredCCBAPI.java b/src/com/p4square/grow/ccb/MonitoredCCBAPI.java new file mode 100644 index 0000000..6903460 --- /dev/null +++ b/src/com/p4square/grow/ccb/MonitoredCCBAPI.java @@ -0,0 +1,68 @@ +package com.p4square.grow.ccb; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; +import com.p4square.ccbapi.CCBAPI; +import com.p4square.ccbapi.model.GetCustomFieldLabelsResponse; +import com.p4square.ccbapi.model.GetIndividualProfilesRequest; +import com.p4square.ccbapi.model.GetIndividualProfilesResponse; + +import java.io.IOException; + +/** + * MonitoredCCBAPI is a CCBAPI decorator which records metrics for each API call. + */ +public class MonitoredCCBAPI implements CCBAPI { + + private final CCBAPI mAPI; + private final MetricRegistry mMetricRegistry; + + public MonitoredCCBAPI(final CCBAPI api, final MetricRegistry metricRegistry) { + if (api == null) { + throw new IllegalArgumentException("api must not be null."); + } + mAPI = api; + + if (metricRegistry == null) { + throw new IllegalArgumentException("metricRegistry must not be null."); + } + mMetricRegistry = metricRegistry; + } + + @Override + public GetCustomFieldLabelsResponse getCustomFieldLabels() throws IOException { + final Timer.Context timer = mMetricRegistry.timer("CCBAPI.getCustomFieldLabels.time").time(); + boolean success = false; + try { + final GetCustomFieldLabelsResponse resp = mAPI.getCustomFieldLabels(); + success = true; + return resp; + } finally { + timer.stop(); + mMetricRegistry.counter("CCBAPI.getCustomFieldLabels.success").inc(success ? 1 : 0); + mMetricRegistry.counter("CCBAPI.getCustomFieldLabels.failure").inc(!success ? 1 : 0); + } + } + + @Override + public GetIndividualProfilesResponse getIndividualProfiles(GetIndividualProfilesRequest request) + throws IOException { + final Timer.Context timer = mMetricRegistry.timer("CCBAPI.getIndividualProfiles").time(); + boolean success = false; + try { + final GetIndividualProfilesResponse resp = mAPI.getIndividualProfiles(request); + mMetricRegistry.counter("CCBAPI.getCustomFieldLabels.count").inc(resp.getIndividuals().size()); + success = true; + return resp; + } finally { + timer.stop(); + mMetricRegistry.counter("CCBAPI.getCustomFieldLabels.success").inc(success ? 1 : 0); + mMetricRegistry.counter("CCBAPI.getCustomFieldLabels.failure").inc(!success ? 1 : 0); + } + } + + @Override + public void close() throws IOException { + mAPI.close(); + } +} |