Add support for SendGrid as Email notification handler

This commit is contained in:
Maxime Dor
2017-09-27 01:55:37 +02:00
parent 61addd297a
commit f3bbc7c7c6
11 changed files with 556 additions and 76 deletions

View File

@@ -20,17 +20,14 @@
package io.kamax.mxisd.threepid.notification;
import io.kamax.mxisd.ThreePid;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.config.threepid.medium.GenericTemplateConfig;
import io.kamax.mxisd.controller.v1.IdentityAPIv1;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,39 +40,20 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@Component
public abstract class GenericTemplateNotificationGenerator implements INotificationGenerator {
public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements INotificationGenerator {
private Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class);
private MatrixConfig mxCfg;
private ServerConfig srvCfg;
private GenericTemplateConfig cfg;
@Autowired
private ApplicationContext app;
public GenericTemplateNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, GenericTemplateConfig cfg) {
this.mxCfg = mxCfg;
this.srvCfg = srvCfg;
super(mxCfg, srvCfg);
this.cfg = cfg;
}
protected String populateForCommon(String body, ThreePid recipient) {
return body;
}
private String populateCommon(String body, ThreePid recipient) {
body = populateForCommon(body, recipient);
String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
body = body.replace("%DOMAIN%", mxCfg.getDomain());
body = body.replace("%DOMAIN_PRETTY%", domainPretty);
body = body.replace("%RECIPIENT_MEDIUM%", recipient.getMedium());
body = body.replace("%RECIPIENT_ADDRESS%", recipient.getAddress());
return body;
}
private String getTemplateContent(String location) {
try {
InputStream is = StringUtils.startsWith(location, "classpath:") ?
@@ -86,65 +64,22 @@ public abstract class GenericTemplateNotificationGenerator implements INotificat
}
}
private String getTemplateAndPopulate(String location, ThreePid recipient) {
return populateCommon(getTemplateContent(location), recipient);
}
@Override
public String getForInvite(IThreePidInviteReply invite) {
ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress());
String templateBody = getTemplateAndPopulate(cfg.getInvite(), tpid);
String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", "");
String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId());
String roomName = invite.getInvite().getProperties().getOrDefault("room_name", "");
String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId());
templateBody = templateBody.replace("%SENDER_ID%", invite.getInvite().getSender().getId());
templateBody = templateBody.replace("%SENDER_NAME%", senderName);
templateBody = templateBody.replace("%SENDER_NAME_OR_ID%", senderNameOrId);
templateBody = templateBody.replace("%INVITE_MEDIUM%", tpid.getMedium());
templateBody = templateBody.replace("%INVITE_ADDRESS%", tpid.getAddress());
templateBody = templateBody.replace("%ROOM_ID%", invite.getInvite().getRoomId());
templateBody = templateBody.replace("%ROOM_NAME%", roomName);
templateBody = templateBody.replace("%ROOM_NAME_OR_ID%", roomNameOrId);
return templateBody;
log.info("Generating notification content for 3PID invite");
return populateForInvite(invite, getTemplateContent(cfg.getInvite()));
}
@Override
public String getForValidation(IThreePidSession session) {
log.info("Generating notification content for 3PID Session validation");
String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getLocal(), session.getThreePid());
String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
session.getThreePid().getMedium(),
session.getId(),
session.getSecret(),
session.getToken());
templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink);
templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken());
return templateBody;
return populateForValidation(session, getTemplateContent(cfg.getSession().getValidation().getLocal()));
}
@Override
public String getForRemoteValidation(IThreePidSession session) {
log.info("Generating notification content for remote-only 3PID session");
String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getRemote(), session.getThreePid());
String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
session.getThreePid().getMedium(),
session.getId(),
session.getSecret(),
session.getToken());
templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink);
templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken());
templateBody = templateBody.replace("%NEXT_URL%", validationLink);
return templateBody;
return populateForRemoteValidation(session, getTemplateContent(cfg.getSession().getValidation().getRemote()));
}
}

View File

@@ -0,0 +1,89 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2017 Maxime Dor
*
* https://max.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification;
import io.kamax.mxisd.ThreePid;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.controller.v1.IdentityAPIv1;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
public abstract class PlaceholderNotificationGenerator {
private MatrixConfig mxCfg;
private ServerConfig srvCfg;
public PlaceholderNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg) {
this.mxCfg = mxCfg;
this.srvCfg = srvCfg;
}
protected String populateForCommon(String input, ThreePid recipient) {
String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
return input
.replace("%DOMAIN%", mxCfg.getDomain())
.replace("%DOMAIN_PRETTY%", domainPretty)
.replace("%RECIPIENT_MEDIUM%", recipient.getMedium())
.replace("%RECIPIENT_ADDRESS%", recipient.getAddress());
}
protected String populateForInvite(IThreePidInviteReply invite, String input) {
ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress());
String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", "");
String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId());
String roomName = invite.getInvite().getProperties().getOrDefault("room_name", "");
String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId());
return populateForCommon(input, tpid)
.replace("%SENDER_ID%", invite.getInvite().getSender().getId())
.replace("%SENDER_NAME%", senderName)
.replace("%SENDER_NAME_OR_ID%", senderNameOrId)
.replace("%INVITE_MEDIUM%", tpid.getMedium())
.replace("%INVITE_ADDRESS%", tpid.getAddress())
.replace("%ROOM_ID%", invite.getInvite().getRoomId())
.replace("%ROOM_NAME%", roomName)
.replace("%ROOM_NAME_OR_ID%", roomNameOrId);
}
protected String populateForValidation(IThreePidSession session, String input) {
String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
session.getThreePid().getMedium(),
session.getId(),
session.getSecret(),
session.getToken()
);
return populateForCommon(input, session.getThreePid())
.replace("%VALIDATION_LINK%", validationLink)
.replace("%VALIDATION_TOKEN%", session.getToken())
.replace("%NEXT_URL%", validationLink);
}
protected String populateForRemoteValidation(IThreePidSession session, String input) {
return populateForValidation(session, input);
}
}

View File

@@ -30,16 +30,21 @@ import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class EmailNotificationHandler extends GenericNotificationHandler<IEmailConnector, IEmailNotificationGenerator> {
public class EmailRawNotificationHandler extends GenericNotificationHandler<IEmailConnector, IEmailNotificationGenerator> {
private EmailConfig cfg;
@Autowired
public EmailNotificationHandler(EmailConfig cfg, List<IEmailNotificationGenerator> generators, List<IEmailConnector> connectors) {
public EmailRawNotificationHandler(EmailConfig cfg, List<IEmailNotificationGenerator> generators, List<IEmailConnector> connectors) {
this.cfg = cfg;
process(connectors, generators);
}
@Override
public String getId() {
return "raw";
}
@Override
public String getMedium() {
return ThreePidMedium.Email.getId();

View File

@@ -40,6 +40,11 @@ public class PhoneNotificationHandler extends GenericNotificationHandler<IPhoneC
process(connectors, generators);
}
@Override
public String getId() {
return "raw";
}
@Override
public String getMedium() {
return ThreePidMedium.PhoneNumber.getId();