diff --git a/src/main/java/com/impactupgrade/nucleus/client/MinistryByTextClient.java b/src/main/java/com/impactupgrade/nucleus/client/MinistryByTextClient.java index c845fdb67..7a8d7ec77 100644 --- a/src/main/java/com/impactupgrade/nucleus/client/MinistryByTextClient.java +++ b/src/main/java/com/impactupgrade/nucleus/client/MinistryByTextClient.java @@ -1,8 +1,6 @@ package com.impactupgrade.nucleus.client; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.impactupgrade.nucleus.dao.HibernateDao; -import com.impactupgrade.nucleus.entity.Organization; import com.impactupgrade.nucleus.environment.Environment; import com.impactupgrade.nucleus.environment.EnvironmentConfig; import com.impactupgrade.nucleus.model.CrmContact; @@ -19,38 +17,22 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; // TODO: To eventually become a mbt-java-client open source lib? -public class MinistryByTextClient { +public class MinistryByTextClient extends OrgConfiguredClient { protected static String AUTH_ENDPOINT = "https://login-qa.ministrybytext.com/connect/token"; protected static String API_ENDPOINT_BASE = "https://api-qa.ministrybytext.com/"; - protected final Environment env; - protected HibernateDao organizationDao; - private final OAuth2.Context oAuth2Context; public MinistryByTextClient(Environment env) { - this.env = env; - this.organizationDao = new HibernateDao<>(Organization.class); + super(env); - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject mbtJson = envJson.getJSONObject("mbt"); + JSONObject mbtJson = getEnvJson().getJSONObject("mbt"); this.oAuth2Context = new OAuth2.ClientCredentialsContext( env.getConfig().mbt.clientId, env.getConfig().mbt.clientSecret, mbtJson.getString("accessToken"), mbtJson.getLong("expiresAt"), mbtJson.getString("refreshToken"), AUTH_ENDPOINT); } - - // TODO: move the code to util/common parent class? - protected Organization getOrganization() { - return organizationDao.getQueryResult( - "from Organization o where o.nucleusApiKey=:apiKey", - query -> { - query.setParameter("apiKey", env.getConfig().apiKey); - } - ).get(); - } public List getGroups(String campusId) { return get(API_ENDPOINT_BASE + "campuses/" + campusId + "/groups", headers(), new GenericType<>() {}); @@ -69,6 +51,15 @@ public Subscriber upsertSubscriber(CrmContact crmContact, String groupId) { return post(API_ENDPOINT_BASE + "campuses/" + env.getConfig().mbt.campusId + "/groups/" + groupId + "/subscribers", subscriber, APPLICATION_JSON, headers(), Subscriber.class); } + protected HttpClient.HeaderBuilder headers() { + String accessToken = oAuth2Context.accessToken(); + if (oAuth2Context.refresh().accessToken() != accessToken) { + // tokens updated - need to update env json config + updateEnvJson("mbt", oAuth2Context); + } + return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); + } + protected Subscriber toMBTSubscriber(CrmContact crmContact) { Subscriber subscriber = new Subscriber(); subscriber.firstName = crmContact.firstName; @@ -115,24 +106,6 @@ public static class SubscriberRelation { public String relationship; } - // TODO: move the code to util/common parent class? - protected HttpClient.HeaderBuilder headers() { - String currentAccessToken = oAuth2Context.accessToken(); - if (currentAccessToken != oAuth2Context.refresh().accessToken()) { - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject mbtJson = envJson.getJSONObject("mbt"); - - mbtJson.put("accessToken", oAuth2Context.accessToken()); - mbtJson.put("expiresAt", oAuth2Context.expiresAt() != null ? oAuth2Context.expiresAt() : null); - mbtJson.put("refreshToken", oAuth2Context.refreshToken()); - org.setEnvironmentJson(envJson); - organizationDao.update(org); - } - - return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); - } - //TODO: remove once done with testing public static void main(String[] args) { Environment env = new Environment() { diff --git a/src/main/java/com/impactupgrade/nucleus/client/OrgConfiguredClient.java b/src/main/java/com/impactupgrade/nucleus/client/OrgConfiguredClient.java new file mode 100644 index 000000000..4073afe45 --- /dev/null +++ b/src/main/java/com/impactupgrade/nucleus/client/OrgConfiguredClient.java @@ -0,0 +1,42 @@ +package com.impactupgrade.nucleus.client; + +import com.impactupgrade.nucleus.dao.HibernateDao; +import com.impactupgrade.nucleus.entity.Organization; +import com.impactupgrade.nucleus.environment.Environment; +import com.impactupgrade.nucleus.util.OAuth2; +import org.json.JSONObject; + +public class OrgConfiguredClient { + + protected final Environment env; + protected final HibernateDao organizationDao; + + public OrgConfiguredClient(Environment env) { + this.env = env; + this.organizationDao = new HibernateDao<>(Organization.class); + } + + protected JSONObject getEnvJson() { + return getOrganization(env.getConfig().apiKey).getEnvironmentJson(); + } + + protected void updateEnvJson(String clientConfigKey, OAuth2.Context context) { + Organization org = getOrganization(env.getConfig().apiKey); + JSONObject envJson = org.getEnvironmentJson(); + JSONObject clientConfigJson = envJson.getJSONObject(clientConfigKey); + + clientConfigJson.put("accessToken", context.accessToken()); + clientConfigJson.put("expiresAt", context.expiresAt() != null ? context.expiresAt() : null); + clientConfigJson.put("refreshToken", context.refreshToken()); + + org.setEnvironmentJson(envJson); + organizationDao.update(org); + } + + private Organization getOrganization(String apiKey) { + return organizationDao.getQueryResult( + "from Organization o where o.nucleusApiKey=:apiKey", + query -> query.setParameter("apiKey", apiKey) + ).get(); + } +} diff --git a/src/main/java/com/impactupgrade/nucleus/client/RaiselyClient.java b/src/main/java/com/impactupgrade/nucleus/client/RaiselyClient.java index c758e4c93..142edf883 100644 --- a/src/main/java/com/impactupgrade/nucleus/client/RaiselyClient.java +++ b/src/main/java/com/impactupgrade/nucleus/client/RaiselyClient.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.impactupgrade.nucleus.dao.HibernateDao; -import com.impactupgrade.nucleus.entity.Organization; import com.impactupgrade.nucleus.environment.Environment; import com.impactupgrade.nucleus.environment.EnvironmentConfig; import com.impactupgrade.nucleus.util.HttpClient; @@ -15,38 +13,23 @@ import static com.impactupgrade.nucleus.util.HttpClient.get; -public class RaiselyClient { +public class RaiselyClient extends OrgConfiguredClient { private static final String RAISELY_API_URL = "https://api.raisely.com/v3"; private static final String AUTH_URL = RAISELY_API_URL + "/login"; - protected final Environment env; - protected HibernateDao organizationDao; - private final OAuth2.Context oAuth2Context; public RaiselyClient(Environment env) { - this.env = env; - this.organizationDao = new HibernateDao<>(Organization.class); + super(env); - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject raiselyJson = envJson.getJSONObject("raisely"); + JSONObject raiselyJson = getEnvJson().getJSONObject("raisely"); this.oAuth2Context = new OAuth2.UsernamePasswordContext( env.getConfig().raisely.username, env.getConfig().raisely.password, Map.of("requestAdminToken", "true"), raiselyJson.getString("accessToken"), raiselyJson.getLong("expiresAt"), raiselyJson.getString("refreshToken"), AUTH_URL); } - protected Organization getOrganization() { - return organizationDao.getQueryResult( - "from Organization o where o.nucleusApiKey=:apiKey", - query -> { - query.setParameter("apiKey", env.getConfig().apiKey); - } - ).get(); - } - //*Note this uses the donation ID from the Stripe metadata. Different from the donation UUID /* * From Raisely Support: @@ -73,19 +56,11 @@ public RaiselyClient.Donation getDonation(String donationId) { } protected HttpClient.HeaderBuilder headers() { - String currentAccessToken = oAuth2Context.accessToken(); - if (currentAccessToken != oAuth2Context.refresh().accessToken()) { - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject raisely = envJson.getJSONObject("raisely"); - - raisely.put("accessToken", oAuth2Context.accessToken()); - raisely.put("expiresAt", oAuth2Context.expiresAt() != null ? oAuth2Context.expiresAt() : null); - raisely.put("refreshToken", oAuth2Context.refreshToken()); - org.setEnvironmentJson(envJson); - organizationDao.update(org); + String accessToken = oAuth2Context.accessToken(); + if (oAuth2Context.refresh().accessToken() != accessToken) { + // tokens updated - need to update config in db + updateEnvJson("raisely", oAuth2Context); } - return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); } diff --git a/src/main/java/com/impactupgrade/nucleus/client/SpokeClient.java b/src/main/java/com/impactupgrade/nucleus/client/SpokeClient.java index ed17344d6..0aebeb9a3 100644 --- a/src/main/java/com/impactupgrade/nucleus/client/SpokeClient.java +++ b/src/main/java/com/impactupgrade/nucleus/client/SpokeClient.java @@ -20,38 +20,23 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; // TODO: To eventually become a spoke-phone-java-client open source lib? -public class SpokeClient { +public class SpokeClient extends OrgConfiguredClient { protected static String AUTH_ENDPOINT = "https://auth.spokephone.com/oauth/token"; protected static String API_ENDPOINT_BASE = "https://integration.spokephone.com/"; - protected final Environment env; - protected HibernateDao organizationDao; - private final OAuth2.Context oAuth2Context; public SpokeClient(Environment env) { - this.env = env; - this.organizationDao = new HibernateDao<>(Organization.class); + super(env); - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject spokeJson = envJson.getJSONObject("spoke"); + JSONObject spokeJson = getEnvJson().getJSONObject("spoke"); this.oAuth2Context = new OAuth2.ClientCredentialsContext( env.getConfig().spoke.clientId, env.getConfig().spoke.clientSecret, spokeJson.getString("accessToken"), spokeJson.getLong("expiresAt"), spokeJson.getString("refreshToken"), AUTH_ENDPOINT); } - protected Organization getOrganization() { - return organizationDao.getQueryResult( - "from Organization o where o.nucleusApiKey=:apiKey", - query -> { - query.setParameter("apiKey", env.getConfig().apiKey); - } - ).get(); - } - public List getPhonebooks() { return get(API_ENDPOINT_BASE + "phonebooks", headers(), new GenericType<>() {}); } @@ -100,6 +85,15 @@ protected Contact toSpokeContact(CrmContact crmContact, String crmName) { return contact; } + protected HttpClient.HeaderBuilder headers() { + String accessToken = oAuth2Context.accessToken(); + if (oAuth2Context.refresh().accessToken() != accessToken) { + // tokens updated - need to update config in db + updateEnvJson("raisely", oAuth2Context); + } + return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); + } + @JsonIgnoreProperties(ignoreUnknown = true) public static class Phonebook { public String id; @@ -129,23 +123,6 @@ public static class ContactRequest { public String countryIso; } - protected HttpClient.HeaderBuilder headers() { - String currentAccessToken = oAuth2Context.accessToken(); - if (currentAccessToken != oAuth2Context.refresh().accessToken()) { - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject spokeJson = envJson.getJSONObject("spoke"); - - spokeJson.put("accessToken", oAuth2Context.accessToken()); - spokeJson.put("expiresAt", oAuth2Context.expiresAt() != null ? oAuth2Context.expiresAt() : null); - spokeJson.put("refreshToken", oAuth2Context.refreshToken()); - org.setEnvironmentJson(envJson); - organizationDao.update(org); - } - - return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); - } - //TODO: remove once done with testing public static void main(String[] args) { Environment env = new Environment() { diff --git a/src/main/java/com/impactupgrade/nucleus/client/VirtuousClient.java b/src/main/java/com/impactupgrade/nucleus/client/VirtuousClient.java index 9e89d8a86..c3ecb9167 100644 --- a/src/main/java/com/impactupgrade/nucleus/client/VirtuousClient.java +++ b/src/main/java/com/impactupgrade/nucleus/client/VirtuousClient.java @@ -3,8 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Strings; -import com.impactupgrade.nucleus.dao.HibernateDao; -import com.impactupgrade.nucleus.entity.Organization; import com.impactupgrade.nucleus.environment.Environment; import com.impactupgrade.nucleus.environment.EnvironmentConfig; import com.impactupgrade.nucleus.util.HttpClient; @@ -25,25 +23,19 @@ import static com.impactupgrade.nucleus.util.HttpClient.put; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -public class VirtuousClient { +public class VirtuousClient extends OrgConfiguredClient { private static final String VIRTUOUS_API_URL = "https://api.virtuoussoftware.com/api"; private static final int DEFAULT_OFFSET = 0; private static final int DEFAULT_LIMIT = 100; - protected final Environment env; - protected HibernateDao organizationDao; - private String apiKey; private final OAuth2.Context oAuth2Context; public VirtuousClient(Environment env) { - this.env = env; - this.organizationDao = new HibernateDao<>(Organization.class); + super(env); - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject virtuousJson = envJson.getJSONObject("virtuous"); + JSONObject virtuousJson = getEnvJson().getJSONObject("virtuous"); this.apiKey = env.getConfig().virtuous.secretKey; this.oAuth2Context = new OAuth2.UsernamePasswordContext( @@ -51,15 +43,6 @@ public VirtuousClient(Environment env) { virtuousJson.getString("accessToken"), virtuousJson.getLong("expiresAt"), virtuousJson.getString("refreshToken"), env.getConfig().virtuous.tokenServerUrl); } - protected Organization getOrganization() { - return organizationDao.getQueryResult( - "from Organization o where o.nucleusApiKey=:apiKey", - query -> { - query.setParameter("apiKey", env.getConfig().apiKey); - } - ).get(); - } - // Contact public Contact createContact(Contact contact) { contact = post(VIRTUOUS_API_URL + "/Contact", contact, APPLICATION_JSON, headers(), Contact.class); @@ -275,19 +258,11 @@ private HttpClient.HeaderBuilder headers() { //If the verification code and user credentials are correct, you will receive a token as seen in the Token authentication above. //To request a new Token after the user enters the verification code, add an OTP header: //curl -d "grant_type=password&username=YOUR_EMAIL&password=YOUR_PASSWORD&otp=YOUR_OTP" -X POST https://api.virtuoussoftware.com/Token - String currentAccessToken = oAuth2Context.accessToken(); - if (currentAccessToken != oAuth2Context.refresh().accessToken()) { - Organization org = getOrganization(); - JSONObject envJson = org.getEnvironmentJson(); - JSONObject virtuousJson = envJson.getJSONObject("virtuous"); - - virtuousJson.put("accessToken", oAuth2Context.accessToken()); - virtuousJson.put("expiresAt", oAuth2Context.expiresAt() != null ? oAuth2Context.expiresAt() : null); - virtuousJson.put("refreshToken", oAuth2Context.refreshToken()); - org.setEnvironmentJson(envJson); - organizationDao.update(org); + String accessToken = oAuth2Context.accessToken(); + if (oAuth2Context.refresh().accessToken() != accessToken) { + // tokens updated - need to update config in db + updateEnvJson("raisely", oAuth2Context); } - return HttpClient.HeaderBuilder.builder().authBearerToken(oAuth2Context.accessToken()); }