Polishing, prepare for proxying 3PID sessions
This commit is contained in:
@@ -42,6 +42,7 @@ public class SessionConfig {
|
||||
public static class PolicySource {
|
||||
|
||||
private boolean enabled;
|
||||
private boolean alwaysValidate;
|
||||
private boolean toLocal;
|
||||
private boolean toRemote;
|
||||
|
||||
@@ -53,6 +54,14 @@ public class SessionConfig {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isAlwaysValidate() {
|
||||
return alwaysValidate;
|
||||
}
|
||||
|
||||
public void setAlwaysValidate(boolean alwaysValidate) {
|
||||
this.alwaysValidate = alwaysValidate;
|
||||
}
|
||||
|
||||
public boolean toLocal() {
|
||||
return toLocal;
|
||||
}
|
||||
@@ -98,6 +107,10 @@ public class SessionConfig {
|
||||
public PolicySource forRemote() {
|
||||
return forRemote;
|
||||
}
|
||||
|
||||
public PolicySource forIf(boolean isLocal) {
|
||||
return isLocal ? forLocal : forRemote;
|
||||
}
|
||||
}
|
||||
|
||||
private PolicyTemplate bind = new PolicyTemplate();
|
||||
|
@@ -45,13 +45,36 @@ public class EmailTemplateConfig {
|
||||
|
||||
public static class Session {
|
||||
|
||||
private String validation;
|
||||
public static class SessionValidation {
|
||||
|
||||
public String getValidation() {
|
||||
private String local;
|
||||
private String remote;
|
||||
|
||||
public String getLocal() {
|
||||
return local;
|
||||
}
|
||||
|
||||
public void setLocal(String local) {
|
||||
this.local = local;
|
||||
}
|
||||
|
||||
public String getRemote() {
|
||||
return remote;
|
||||
}
|
||||
|
||||
public void setRemote(String remote) {
|
||||
this.remote = remote;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SessionValidation validation;
|
||||
|
||||
public SessionValidation getValidation() {
|
||||
return validation;
|
||||
}
|
||||
|
||||
public void setValidation(String validation) {
|
||||
public void setValidation(SessionValidation validation) {
|
||||
this.validation = validation;
|
||||
}
|
||||
|
||||
@@ -76,7 +99,9 @@ public class EmailTemplateConfig {
|
||||
public void build() {
|
||||
log.info("--- E-mail Generator templates config ---");
|
||||
log.info("Invite: {}", getName(getInvite()));
|
||||
log.info("Session validation: {}", getName(getSession().getValidation()));
|
||||
log.info("Session validation:");
|
||||
log.info("\tLocal: {}", getName(getSession().getValidation().getLocal()));
|
||||
log.info("\tRemote: {}", getName(getSession().getValidation().getRemote()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.controller.v1.remote;
|
||||
|
||||
public class RemoteIdentityAPIv1 {
|
||||
|
||||
public static final String BASE = "/_matrix/identity-remote/api/v1";
|
||||
|
||||
}
|
@@ -20,14 +20,13 @@
|
||||
|
||||
package io.kamax.mxisd.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ResponseStatus(value = HttpStatus.FORBIDDEN)
|
||||
public class NotAllowedException extends RuntimeException {
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
public class NotAllowedException extends MatrixException {
|
||||
|
||||
public NotAllowedException(String s) {
|
||||
super(s);
|
||||
super(HttpStatus.SC_FORBIDDEN, "M_FORBIDDEN", s);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -31,4 +31,6 @@ public interface INotificationHandler {
|
||||
|
||||
void sendForValidation(IThreePidSession session);
|
||||
|
||||
void sendForRemoteValidation(IThreePidSession session);
|
||||
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ public class NotificationManager {
|
||||
}
|
||||
|
||||
public void sendforRemoteValidation(IThreePidSession session) {
|
||||
throw new NotImplementedException("Remote publish of 3PID bind");
|
||||
ensureMedium(session.getThreePid().getMedium()).sendForRemoteValidation(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -114,24 +114,14 @@ public class SessionMananger {
|
||||
} else {
|
||||
log.info("No existing session for {}", tpid);
|
||||
|
||||
boolean isLocalDomain = isLocal(tpid);
|
||||
log.info("Is 3PID bound to local domain? {}", isLocalDomain);
|
||||
boolean isLocal = isLocal(tpid);
|
||||
log.info("Is 3PID bound to local domain? {}", isLocal);
|
||||
|
||||
if (isLocalDomain && (!policy.forLocal().isEnabled() || !policy.forLocal().toLocal())) {
|
||||
throw new NotAllowedException("Validating local 3PID is not allowed");
|
||||
}
|
||||
|
||||
// We lookup if the 3PID is already known locally.
|
||||
boolean knownLocal = isKnownLocal(tpid);
|
||||
log.info("Mapping with {} is " + (knownLocal ? "already" : "not") + " known locally", tpid);
|
||||
|
||||
if (!isLocalDomain && (
|
||||
!policy.forRemote().isEnabled() || (
|
||||
!policy.forRemote().toLocal() &&
|
||||
!policy.forRemote().toRemote()
|
||||
)
|
||||
)) {
|
||||
throw new NotAllowedException("Validating unknown remote 3PID is not allowed");
|
||||
// This might need a configuration by medium type?
|
||||
SessionConfig.Policy.PolicyTemplate.PolicySource policySource = policy.forIf(isLocal);
|
||||
if (!policySource.isEnabled() || (!policySource.toLocal() && !policySource.toRemote())) {
|
||||
log.info("Session for {}: cancelled due to policy", tpid);
|
||||
throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
|
||||
}
|
||||
|
||||
String sessionId;
|
||||
@@ -144,14 +134,12 @@ public class SessionMananger {
|
||||
log.info("Generated new session {} to validate {} from server {}", sessionId, tpid, server);
|
||||
|
||||
// This might need a configuration by medium type?
|
||||
if (!isLocalDomain) {
|
||||
if (policy.forRemote().toLocal() && policy.forRemote().toRemote()) {
|
||||
log.info("Session {} for {}: sending local validation notification", sessionId, tpid);
|
||||
notifMgr.sendForValidation(session);
|
||||
} else {
|
||||
log.info("Session {} for {}: sending remote-only validation notification", sessionId, tpid);
|
||||
notifMgr.sendforRemoteValidation(session);
|
||||
}
|
||||
if (policySource.toLocal()) {
|
||||
log.info("Session {} for {}: sending local validation notification", sessionId, tpid);
|
||||
notifMgr.sendForValidation(session);
|
||||
} else {
|
||||
log.info("Session {} for {}: sending remote-only validation notification", sessionId, tpid);
|
||||
notifMgr.sendforRemoteValidation(session);
|
||||
}
|
||||
|
||||
storage.insertThreePidSession(session.getDao());
|
||||
|
@@ -33,6 +33,6 @@ public interface INotificationGenerator {
|
||||
|
||||
String getForValidation(IThreePidSession session);
|
||||
|
||||
String getForRemotePublishingValidation(IThreePidSession session);
|
||||
String getForRemoteValidation(IThreePidSession session);
|
||||
|
||||
}
|
||||
|
@@ -26,8 +26,8 @@ import io.kamax.mxisd.config.ServerConfig;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailTemplateConfig;
|
||||
import io.kamax.mxisd.controller.v1.IdentityAPIv1;
|
||||
import io.kamax.mxisd.controller.v1.remote.RemoteIdentityAPIv1;
|
||||
import io.kamax.mxisd.exception.InternalServerError;
|
||||
import io.kamax.mxisd.exception.NotImplementedException;
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import io.kamax.mxisd.threepid.session.IThreePidSession;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@@ -121,8 +121,9 @@ public class EmailNotificationGenerator implements IEmailNotificationGenerator {
|
||||
@Override
|
||||
public String getForValidation(IThreePidSession session) {
|
||||
log.info("Generating notification content for 3PID Session validation");
|
||||
String templateBody = getTemplateAndPopulate(templateCfg.getSession().getValidation(), session.getThreePid());
|
||||
String templateBody = getTemplateAndPopulate(templateCfg.getSession().getValidation().getLocal(), session.getThreePid());
|
||||
|
||||
// FIXME should have a global link builder, most likely in the SDK?
|
||||
String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.BASE +
|
||||
"/validate/" + session.getThreePid().getMedium() +
|
||||
"/submitToken?sid=" + session.getId() + "&client_secret=" + session.getSecret() +
|
||||
@@ -135,8 +136,19 @@ public class EmailNotificationGenerator implements IEmailNotificationGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForRemotePublishingValidation(IThreePidSession session) {
|
||||
throw new NotImplementedException("");
|
||||
public String getForRemoteValidation(IThreePidSession session) {
|
||||
log.info("Generating notification content for 3PID Session validation");
|
||||
String templateBody = getTemplateAndPopulate(templateCfg.getSession().getValidation().getLocal(), session.getThreePid());
|
||||
|
||||
// FIXME should have a global link builder, specific to mxisd
|
||||
String nextStepLink = srvCfg.getPublicUrl() + RemoteIdentityAPIv1.BASE +
|
||||
"/validate/requestToken?sid=" + session.getId() + "&client_secret=" + session.getSecret();
|
||||
|
||||
templateBody = templateBody.replace("%SESSION_ID%", session.getId());
|
||||
templateBody = templateBody.replace("%SESSION_SECRET%", session.getSecret());
|
||||
templateBody = templateBody.replace("%NEXT_STEP_LINK%", nextStepLink);
|
||||
|
||||
return templateBody;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@ public class EmailNotificationHandler implements INotificationHandler {
|
||||
@Autowired
|
||||
public EmailNotificationHandler(EmailConfig cfg, List<IEmailNotificationGenerator> generators, List<IEmailConnector> connectors) {
|
||||
this.cfg = cfg;
|
||||
|
||||
generator = generators.stream()
|
||||
.filter(o -> StringUtils.equals(cfg.getGenerator(), o.getId()))
|
||||
.findFirst()
|
||||
@@ -59,24 +60,28 @@ public class EmailNotificationHandler implements INotificationHandler {
|
||||
return ThreePidMedium.Email.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendForInvite(IThreePidInviteReply invite) {
|
||||
private void send(String recipient, String content) {
|
||||
connector.send(
|
||||
cfg.getIdentity().getFrom(),
|
||||
cfg.getIdentity().getName(),
|
||||
invite.getInvite().getAddress(),
|
||||
generator.getForInvite(invite)
|
||||
recipient,
|
||||
content
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendForInvite(IThreePidInviteReply invite) {
|
||||
send(invite.getInvite().getAddress(), generator.getForInvite(invite));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendForValidation(IThreePidSession session) {
|
||||
connector.send(
|
||||
cfg.getIdentity().getFrom(),
|
||||
cfg.getIdentity().getName(),
|
||||
session.getThreePid().getAddress(),
|
||||
generator.getForValidation(session)
|
||||
);
|
||||
send(session.getThreePid().getAddress(), generator.getForValidation(session));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendForRemoteValidation(IThreePidSession session) {
|
||||
send(session.getThreePid().getAddress(), generator.getForRemoteValidation(session));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -81,17 +81,19 @@ threepid:
|
||||
template:
|
||||
invite: 'classpath:email/invite-template.eml'
|
||||
session:
|
||||
validation: 'classpath:email/validate-template.eml'
|
||||
validation:
|
||||
local: 'classpath:email/validate-local-template.eml'
|
||||
remote: 'classpath:email/validate-remote-template.eml'
|
||||
|
||||
session.policy.validation:
|
||||
enabled: true
|
||||
forLocal:
|
||||
enabled: true
|
||||
toLocal: true
|
||||
toLocal: true # This should not be changed unless you know exactly the implications!
|
||||
toRemote: true
|
||||
forRemote:
|
||||
enabled: true
|
||||
toLocal: true # This should not be changed unless you know exactly the implications!
|
||||
toLocal: true
|
||||
toRemote: true
|
||||
|
||||
storage:
|
||||
|
91
src/main/resources/email/validate-local-template.eml
Normal file
91
src/main/resources/email/validate-local-template.eml
Normal file
@@ -0,0 +1,91 @@
|
||||
Subject: Your Matrix Validation Token
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
Hello there!
|
||||
|
||||
We have received a request to link this email address with your Matrix account.
|
||||
|
||||
If it was really you who made this request, you can click on the following link to
|
||||
complete the verification of your email address:
|
||||
|
||||
%VALIDATION_LINK%
|
||||
|
||||
If you didn't make this request, you can safely disregard this email.
|
||||
|
||||
Thanks!
|
||||
|
||||
%DOMAIN_PRETTY% Admins
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: multipart/related;
|
||||
boundary="M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR";
|
||||
type="text/html"
|
||||
|
||||
--M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#page {
|
||||
font-family: 'Open Sans', Helvetica, Arial, Sans-Serif;
|
||||
font-color: #454545;
|
||||
font-size: 12pt;
|
||||
width: 100%%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#inner {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
.notif_link a, .footer a {
|
||||
color: #76CFA6 ! important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table id="page">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td id="inner">
|
||||
<p>Hello there!</p>
|
||||
|
||||
<p>We have received a request to link this email address with your Matrix account.</p>
|
||||
|
||||
<p>If it was really you who made this request, you can click on the following link to
|
||||
complete the verification of your email address:</p>
|
||||
|
||||
<p><a href="%VALIDATION_LINK%">Complete email verification</a></p>
|
||||
|
||||
<p>If you didn't make this request, you can safely disregard this email.</p>
|
||||
|
||||
<p>Thanks!</p>
|
||||
|
||||
<p>%DOMAIN_PRETTY% Admins</p>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
--M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR--
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ--
|
@@ -1,66 +0,0 @@
|
||||
Subject: Your Matrix Validation Token
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
Hello,
|
||||
|
||||
We have received a request to link this email address with a Matrix account.
|
||||
If this was you who made this request, you may use the following link to complete the verification of your email address:
|
||||
|
||||
%VALIDATION_LINK%
|
||||
|
||||
If your client requires a code, the code is %VALIDATION_TOKEN%
|
||||
|
||||
If you aren't aware of making such a request, please disregard this email.
|
||||
|
||||
Regards,
|
||||
%DOMAIN_PRETTY% Admins
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Myriad Pro", "Myriad", Helvetica, Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
|
||||
<p>We have received a request to link this email address with a Matrix account.
|
||||
If this was you who made this request, you may use the following link to
|
||||
complete the verification of your email address:</p>
|
||||
|
||||
<p><a href="%VALIDATION_LINK%">Complete email verification</a></p>
|
||||
|
||||
<p>...or copy this link into your web browser:</p>
|
||||
|
||||
<p>%VALIDATION_LINK%</p>
|
||||
|
||||
<p>If your client requires a code, the code is %VALIDATION_TOKEN%</p>
|
||||
|
||||
<p>If you aren't aware of making such a request, please disregard this
|
||||
email.</p>
|
||||
|
||||
<br>
|
||||
<p>Regards,<br>
|
||||
%DOMAIN_PRETTY% Admins</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ--
|
Reference in New Issue
Block a user