From 0ab95e2276f23eeb4051cbf73e72427233fed441 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Thu, 8 Oct 2020 19:23:37 -0400 Subject: [PATCH] WIP. disable tracking for sendgrid subusers --- .../email/sendgrid/SendgridEmailDriver.java | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/bubble-server/src/main/java/bubble/cloud/email/sendgrid/SendgridEmailDriver.java b/bubble-server/src/main/java/bubble/cloud/email/sendgrid/SendgridEmailDriver.java index e7d33814..a07faee4 100644 --- a/bubble-server/src/main/java/bubble/cloud/email/sendgrid/SendgridEmailDriver.java +++ b/bubble-server/src/main/java/bubble/cloud/email/sendgrid/SendgridEmailDriver.java @@ -11,8 +11,8 @@ import bubble.model.account.Account; import bubble.model.cloud.CloudCredentials; import bubble.model.cloud.CloudService; import bubble.server.BubbleConfiguration; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.*; -import org.cobbzilla.util.http.HttpMethods; import org.cobbzilla.util.http.HttpRequestBean; import org.cobbzilla.util.http.HttpResponseBean; @@ -27,7 +27,9 @@ import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.apache.http.HttpHeaders.CONTENT_TYPE; import static org.cobbzilla.util.daemon.ZillaRuntime.*; import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; +import static org.cobbzilla.util.http.HttpMethods.*; import static org.cobbzilla.util.http.HttpUtil.getResponse; +import static org.cobbzilla.util.json.JsonUtil.COMPACT_MAPPER; import static org.cobbzilla.util.json.JsonUtil.json; import static org.cobbzilla.util.security.CryptoUtil.generatePassword; import static org.cobbzilla.wizard.model.IdentifiableBase.DEFAULT_SHORT_ID_LENGTH; @@ -39,9 +41,20 @@ public class SendgridEmailDriver extends SmtpEmailDriver { public static final String SENDGRID_SMTP = "smtp.sendgrid.net"; public static final String SG_API_BASE = "https://api.sendgrid.com/v3/"; + public static final String HEADER_SENDGRID_ON_BEHALF_OF = "On-Behalf-Of"; private static final String PARAM_PARENT_SERVICE = "parentService"; + public static final String SUBUSERS_URI = "subusers"; + public static final String IPS_URI = "ips"; + + public static final String TRACKING_SETTINGS_URI = "tracking_settings"; + public static final String TRACKING_CLICK = "click"; + public static final String TRACKING_GA = "google_analytics"; + public static final String TRACKING_OPEN = "open"; + public static final String TRACKING_SUBSCRIPTION = "subscription"; + public static final String[] TRACKING_TYPES = {TRACKING_CLICK, TRACKING_GA, TRACKING_OPEN, TRACKING_SUBSCRIPTION}; + @Override protected boolean isServiceCompatible(final String serviceHost) { return SENDGRID_SMTP.equals(serviceHost); } @@ -54,18 +67,26 @@ public class SendgridEmailDriver extends SmtpEmailDriver { return super.setupDelegatedCloudService(configuration, parentService, delegatedService); } - final String sgIpsJson = doRequest("ips", HttpMethods.GET, null, parentService); + final String sgIpsJson = doRequest(IPS_URI, GET, null, parentService); final List> sgIps = json(sgIpsJson, List.class); if (empty(sgIps)) die("No IPs set for the specified main Sendgrid user"); final String sgIp = (String) sgIps.get(0).get("ip"); - final Account accountWithDelegate = configuration.getBean(AccountDAO.class) - .findByUuid(delegatedService.getAccount()); + // generate a subuser name and password + final AccountDAO accountDAO = configuration.getBean(AccountDAO.class); + final Account accountWithDelegate = accountDAO.findByUuid(delegatedService.getAccount()); final String user = uuid().substring(0, DEFAULT_SHORT_ID_LENGTH); - String password = generatePassword(MIN_KEY_LENGTH, MIN_DISTINCT_LENGTH); - final CreateSubuserRequest data = new CreateSubuserRequest(user, accountWithDelegate.getEmail(), password, - new String[]{ sgIp }); - doRequest("subusers", HttpMethods.POST, json(data), parentService); + final String password = generatePassword(MIN_KEY_LENGTH, MIN_DISTINCT_LENGTH); + + // create subuser + final CreateSubuserRequest data = new CreateSubuserRequest(user, accountWithDelegate.getEmail(), password, new String[]{sgIp}); + final String responseJson = doRequest(SUBUSERS_URI, POST, json(data, COMPACT_MAPPER), parentService); + final CreateSubuserResponse subuser = json(responseJson, CreateSubuserResponse.class, COMPACT_MAPPER); + + // disable all tracking for subuser + for (String trackingType : TRACKING_TYPES) { + doRequest(TRACKING_SETTINGS_URI+"/"+trackingType, PATCH, DISABLE_TRACKING_JSON, parentService, subuser.getUsername()); + } final CloudCredentials credentials = delegatedService.getCredentials(); credentials.setParam(PARAM_USER, user) @@ -86,17 +107,30 @@ public class SendgridEmailDriver extends SmtpEmailDriver { final String user = service.getCredentials().getParam(PARAM_USER); if (empty(user)) return; - doRequest("subusers/" + user, HttpMethods.DELETE, null, parentService); + doRequest(SUBUSERS_URI + "/" + user, DELETE, null, parentService); } - private String doRequest(@NonNull final String uri, @NonNull final String method, @Nullable final String json, + private String doRequest(@NonNull final String uri, + @NonNull final String method, + @Nullable final String json, @NonNull CloudService parentService) { + return doRequest(uri, method, json, parentService, null); + } + + private String doRequest(@NonNull final String uri, + @NonNull final String method, + @Nullable final String json, + @NonNull CloudService parentService, + String onBehalfOf) { final HttpRequestBean request = new HttpRequestBean(); request.setMethod(method) .setUri(SG_API_BASE + uri) .setEntity(json) .setHeader(CONTENT_TYPE, APPLICATION_JSON) .setHeader(AUTHORIZATION, "Bearer " + parentService.getCredentials().getParam(PARAM_PASSWORD)); + if (onBehalfOf != null) { + request.setHeader(HEADER_SENDGRID_ON_BEHALF_OF, onBehalfOf); + } final HttpResponseBean response; try { @@ -107,16 +141,30 @@ public class SendgridEmailDriver extends SmtpEmailDriver { if (!response.isOk()) { return die("doRequest(" + uri + "): HTTP " + response.getStatus() + " : " + response.getEntityString()); } - return response.getEntityString(); } @AllArgsConstructor @NoArgsConstructor - private class CreateSubuserRequest { + private static class CreateSubuserRequest { @Getter @Setter private String username; @Getter @Setter private String email; @Getter @Setter private String password; @Getter @Setter private String[] ips; } + @JsonIgnoreProperties(ignoreUnknown=true) + private static class CreateSubuserResponse { + @Getter @Setter private String username; + @Getter @Setter private Long user_id; + @Getter @Setter private String email; + } + + @AllArgsConstructor @NoArgsConstructor + private static class TrackingSettingsRequest { + @Getter @Setter private boolean enabled = false; + } + + public static final TrackingSettingsRequest DISABLE_TRACKING = new TrackingSettingsRequest(false); + public static final String DISABLE_TRACKING_JSON = json(DISABLE_TRACKING, COMPACT_MAPPER); + }