diff --git a/docs/threepids/session/session-views.md b/docs/threepids/session/session-views.md
index 885ade6..db263b7 100644
--- a/docs/threepids/session/session-views.md
+++ b/docs/threepids/session/session-views.md
@@ -8,81 +8,27 @@ Pseudo-configuration to illustrate the structure:
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
view:
session:
- local:
- onTokenSubmit:
- success: '/path/to/session/local/tokenSubmitSuccess-page.html'
- failure: '/path/to/session/local/tokenSubmitFailure-page.html'
- localRemote:
- onTokenSubmit:
- success: '/path/to/session/localRemote/tokenSubmitSuccess-page.html'
- failure: '/path/to/session/local/tokenSubmitFailure-page.html'
- remote:
- onRequest:
- success: '/path/to/session/remote/requestSuccess-page.html'
- failure: '/path/to/session/remote/requestFailure-page.html'
- onCheck:
- success: '/path/to/session/remote/checkSuccess-page.html'
- failure: '/path/to/session/remote/checkFailure-page.html'
+ onTokenSubmit:
+ success: '/path/to/session/tokenSubmitSuccess-page.html'
+ failure: '/path/to/session/tokenSubmitFailure-page.html'
# CONFIGURATION EXAMPLE
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
```
-3PID session are divided into three config sections:
-- `local` for local-only 3PID sessions
-- `localRemote` for local 3PID sessions that can also be turned into remote sessions, if the user so desires
-- `remote` for remote-only 3PID sessions
-
-Each section contains a sub-key per support event. Finally, a `success` and `failure` key is available depending on the
-outcome of the request.
-
-## Local
-### onTokenSubmit
+`view.session`:
This is triggered when a user submit a validation token for a 3PID session. It is typically visited when clicking the
link in a validation email.
The template should typically inform the user that the validation was successful and to go back in their Matrix client
-to finish the validation process.
+to finish the validation process, or that the validation failed.
-#### Placeholders
+Two configuration keys are available that accept paths to HTML templates:
+- `success`
+- `failure`
+
+## Placeholders
+### Success
No object/placeholder are currently available.
-## Local & Remote
-### onTokenSubmit
-This is triggered when a user submit a validation token for a 3PID session. It is typically visited when clicking the
-link in a validation email.
-
-The template should typically inform the user that their 3PID address will not yet be publicly/globally usable. In case
-they want to make it, they should start a Remote 3PID session with a given link or that they can go back to their Matrix
-client if they do not wish to proceed any further.
-
-#### Placeholders
-##### Success
-`text` can be used to display the link to start a Remote 3PID session.
-
-##### Failure
-No object/placeholder are currently available.
-
-## Remote
-### onRequest
-This is triggered when a user starts a Remote 3PID session, usually from a link produced in the `local.onTokenSubmit`
-view or in a remote-only 3PID notification.
-
-The template should typically inform the user that the remote creation was successful, followed the instructions sent by
-the remote Identity server and, once that is done, click a link to validate the session.
-
-#### Placeholders
-##### Success
-`text` can be used to display the link to validate the Remote 3PID session.
-
-##### Failure
-No object/placeholder are currently available.
-
-### onCheck
-This is triggered when a user attempts to inform the Identity server that the Remote 3PID session has been validated
-with the remote Identity server.
-
-The template should typically inform the user that the validation was successful and to go back in their Matrix client
-to finish the validation process.
-
-#### Placeholders
+### Failure
No object/placeholder are currently available.
diff --git a/docs/threepids/session/session.md b/docs/threepids/session/session.md
index 60dce6b..71dbb41 100644
--- a/docs/threepids/session/session.md
+++ b/docs/threepids/session/session.md
@@ -1,9 +1,8 @@
# 3PID Sessions
- [Overview](#overview)
-- [Purpose](#purpose)
-- [Federation](#federation)
- - [3PID scope](#3pid-scope)
- - [Session scope](#session-scope)
+- [Restrictions](#restrictions)
+ - [Bindings](#bindings)
+ - [Federation](#federation)
- [Notifications](#notifications)
- [Email](#email)
- [Phone numbers](#msisdn-(phone-numbers))
@@ -11,28 +10,39 @@
- [Configuration](#configuration)
- [Web views](#web-views)
- [Scenarios](#scenarios)
- - [Default](#default)
- - [Local sessions only](#local-sessions-only)
- - [Remote sessions only](#remote-sessions-only)
- [Sessions disabled](#sessions-disabled)
## Overview
When adding an email, a phone number or any other kind of 3PID (Third-Party Identifier) in a Matrix client,
the identity server is contacted to validate the 3PID.
-To validate the 3PID the identity server sends a message to the 3PID (e.g. an
-email) with a hyperlink back to a web-page managed by the identity server to
-confirm ownership of the 3PID.
+To validate the 3PID, the identity server creates a session associated with a secret token. That token is sent via a message
+to the 3PID (e.g. an email) with a the necessary info so the user can submit them to the Identity Server, confirm ownership
+of the 3PID.
-Once this 3PID is validated, the Homeserver will publish the user Matrix ID on the Identity Server and
-add this 3PID to the Matrix account which initiated the request.
+Once this 3PID is validated, the Homeserver will request that the Identity Server links the provided user Matrix ID with
+the 3PID session and finally add the 3PID to its own data store.
This serves two purposes:
- Add the 3PID as an administrative/login info for the Homeserver directly
-- Publish, or *Bind*, the 3PID so it can be queried from Homeservers and clients when inviting someone in a room
+- Links, called *Bind*, the 3PID so it can be queried from Homeservers and clients when inviting someone in a room
by a 3PID, allowing it to be resolved to a Matrix ID.
-## Federation
+## Restrictions
+### Bindings
+mxisd does not store bindings directly. While a user can see its email, phone number or any other 3PID in its
+settings/profile, it does **NOT** mean it is published/saved anywhere or can be used to invite/search the user.
+
+Identity stores are the ones holding such data, irrelevant if a user added a 3PID to their profile. When queried for
+bindings, mxisd will query Identity stores which are responsible to store this kind of information.
+
+Therefore, by default, any 3PID added to a user profile which is NOT within a configured and enabled Identity backend
+will simply not be usable for search or invites, **even on the same Homeserver!**
+
+To have such 3PID bindings available for search and invite queries on synapse, use its dedicated
+[Identity store](../../stores/synapse.md).
+
+### Federation
In a federated set up, identity servers must cooperate to find the Matrix ID associated with a 3PID.
Federation is based on the principle that each server is responsible for its own (dns) domain.
@@ -43,61 +53,15 @@ Example: a user from Homeserver `example.org` adds an email `john@example.com`.
Federated identity servers would try to find the identity server at `example.com` and ask it for the Matrix ID of associated with `john@example.com`.
Nevertheless, Matrix users might add 3PIDs that are not associated to a domain, for example telephone numbers.
-Or they might even add 3PIDs associated to a different domain (such as an email address hosted by gmail).
-Such 3PIDs cannot be resolved in a federated way.
+Or they might even add 3PIDs associated to a different domain (such as an email address hosted by Gmail).
+Such 3PIDs cannot be resolved in a federated way and will not be found from other servers.
Example: a user from Homeserver `example.org` adds an email `john@gmail.com`.
If a federated lookup was performed, Identity servers would try to find the 3PID bind at the `gmail.com` server, and
not `example.org`.
-In order to resolve such 3PIDs, i.e. 3PIDs that cannot be resolved in a Federated way, an identity server can be configured such that
-- 3PIDs that cannot be resolved locally or using federation, are fowarded to another global identity server.
-- registration of new 3PIDs that cannot be looked up in a federated fashion, is forwarded to another global identity server.
-
-By forwarding a 3PIDs registration the identity creates a *Remote session* and *Remote bind*, effectively starting a new 3PID session with another Identity server on
-behalf of the user.
-
-To ensure lookup works consistency within the current Matrix network, the central Matrix.org Identity Server should be
-used to store *remote* sessions and binds.
-
-However, at the time of writing, the Matrix specification and the central Matrix.org servers do not allow to remote a 3PID bind.
-This means that once a 3PID is published (email, phone number, etc.), it cannot be easily removed
-and would require contacting the Matrix.org administrators for each bind individually.
-This poses a privacy, control and security concern, especially for groups/corporations that want to keep a tight control
-on where such identifiers can be made publicly visible.
-
-To ensure full control, validation management relies on two concepts:
-- The scope of 3PID being validated
-- The scope of 3PID sessions that should be possible/offered
-
-### 3PID scope
-3PID can either be scoped as local or remote.
-
-Local means that they can be looked up using federation and that such a federation call would end up on the local
-Identity Server.
-Remote means that they cannot be lookup using federation or that a federation call would not end up on the local
-Identity Server.
-
-Email addresses can either be local or remote 3PID, depending on the domain. If the address is one from the configured
-domain in the Identity server, it will be scoped as local. If it is from another domain, it will be as remote.
-
-Phone number can only be scoped as remote, since there is currently no way to perform DNS queries that would lead back
-to the Identity server who validated the phone number.
-
-### Session scope
-Sessions can be scoped as:
-- Local only - validate 3PIDs directly, do not allow the creation of 3PID sessions on a remote Identity server.
-- Local and Remote - validate 3PIDs directly, offer users to option to also validate and bind 3PID on another server.
-- Remote only - validate and bind 3PIDs on another server, no validation or bind done locally.
-
----
-
-**IMPORTANT NOTE:** mxisd does not store bindings directly. While a user can see its email, phone number or any other
-3PID in its settings/profile, it does **NOT** mean it is published anywhere and can be used to invite/search the user.
-Identity stores are the ones holding such data.
-If you still want added arbitrary 3PIDs to be discoverable on a synapse Homeserver, use the corresponding [Identity store](../../stores/synapse.md).
-
-See the [Scenarios](#scenarios) for more info on how and why.
+As mxisd is built for self-hosted use cases, mainly for orgs/corps, this is usually not a problem for emails.
+Sadly, there is currently no mechanism to make this work for phone numbers.
## Notifications
3PIDs are validated by sending a pre-formatted message containing a token to that 3PID address, which must be given to the
@@ -126,50 +90,28 @@ Connectors:
## Usage
### Configuration
-The following example of configuration (incomplete extract) shows which items are relevant for 3PID sessions.
+The following example of configuration shows which items are relevant for 3PID sessions.
**IMPORTANT:** Most configuration items shown have default values and should not be included in your own configuration
file unless you want to specifically overwrite them.
```yaml
# CONFIGURATION EXAMPLE
-# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
+# DO NOT COPY/PASTE AS-IS IN YOUR CONFIGURATION
+
session:
policy:
validation:
enabled: true
- forLocal:
- enabled: true
- toLocal: true
- toRemote:
- enabled: true
- server: 'configExample' # Not to be included in config! Already present in default config!
- forRemote:
- enabled: true
- toLocal: true
- toRemote:
- enabled: true
- server: 'configExample' # Not to be included in config! Already present in default config!
unbind:
fraudulent:
sendWarning: true
-# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
+
+# DO NOT COPY/PASTE AS-IS IN YOUR CONFIGURATION
# CONFIGURATION EXAMPLE
```
`session.policy.validation` is the core configuration to control what users configured to use your Identity server
-are allowed to do in terms of 3PID sessions.
-
-The policy has a global on/off switch for 3PID sessions using `.enabled`
-It is also divided into two sections: `forLocal` and `forRemote` which refers to the 3PID scopes.
-
-Each scope is divided into three parts:
-- global on/off switch for 3PID sessions using `.enabled`
-- `toLocal` allowing or not local 3PID session validations
-- `toRemote` allowing or not remote 3PID session validations and to which server such sessions should be sent.
- `.server` takes a Matrix Identity server list label. Only the first server in the list is currently used.
-
-If both `toLocal` and `toRemote` are enabled, the user will be offered to initiate a remote session once their 3PID
-locally validated.
+are allowed to do in terms of 3PID sessions. The policy has a global on/off switch for 3PID sessions using `.enabled`
---
@@ -188,107 +130,13 @@ See [the dedicated document](session-views.md)
on how to configure/customize/brand those pages to your liking.
### Scenarios
-It is important to keep in mind that mxisd does not create bindings, irrelevant if a user added a 3PID to their profile.
-Instead, when queried for bindings, mxisd will query Identity stores which are responsible to store this kind of information.
-
-This has the side effect that any 3PID added to a user profile which is NOT within a configured and enabled Identity backend
-will simply not be usable for search or invites, **even on the same Homeserver!**
-mxisd does not store binds on purpose, as one of its primary goal is to ensure maximum compatibility with federation
-and the rest of the Matrix ecosystem is preserved.
-
-Nonetheless, because mxisd also aims at offering support for tight control over identity data, it is possible to have
-such 3PID bindings available for search and invite queries on synapse with the corresponding [Identity store](../../stores/synapse.md).
-
-See the [Local sessions only](#local-sessions-only) use case for more information on how to configure.
-
-#### Default
-By default, mxisd allows the following:
-
-| | Local Session | Remote Session |
-|-----------------|-------------------|----------------|
-| **Local 3PID** | Yes | Yes, offered |
-| **Remote 3PID** | No, Remote forced | Yes |
-
-This is usually what people expect and will feel natural to users and does not involve further integration.
-
-This allows to stay in control for e-mail addresses which domain matches your Matrix environment, still making them
-discoverable with federation but not recorded in a 3rd party Identity server which is not under your control.
-Users still get the possibility to publish globally their address if needed.
-
-Other e-mail addresses and phone number will be redirected to remote sessions to ensure full compatibility with the Matrix
-ecosystem and other federated servers.
-
-#### Local sessions only
-**NOTE:** This does not affect 3PID lookups (queries to find Matrix IDs). See [Federation](../../features/federation.md)
-to disable remote lookup for those.
-
-This configuration ensures maximum confidentiality and privacy.
-Typical use cases:
-- Private Homeserver, not federated
-- Internal Homeserver without direct Internet access
-- Custom product based on Matrix which does not federate
-
-No 3PID will be sent to a remote Identity server and all validation will be performed locally.
-On the flip side, people with *Remote* 3PID scopes will not be found from other servers.
-
-Use the following values:
-```yaml
-session:
- policy:
- validation:
- enabled: true
- forLocal:
- enabled: true
- toLocal: true
- toRemote:
- enabled: false
- forRemote:
- enabled: true
- toLocal: true
- toRemote:
- enabled: false
-```
-
-**IMPORTANT**: When using local-only mode and if you are using synapse, you will also need to enable its dedicated Identity
-store if you want user searches and invites to work. To do so, see the [dedicated document](../../stores/synapse.md).
-
-#### Remote sessions only
-This configuration ensures all 3PID are made public for maximum compatibility and reach within the Matrix ecosystem, at
-the cost of confidentiality and privacy.
-
-Typical use cases:
-- Public Homeserver
-- Homeserver with registration enabled
-
-Use the following values:
-```yaml
-session:
- policy:
- validation:
- enabled: true
- forLocal:
- enabled: true
- toLocal: false
- toRemote:
- enabled: true
- forRemote:
- enabled: true
- toLocal: false
- toRemote:
- enabled: true
-```
-
#### Sessions disabled
-This configuration would disable 3PID session altogether, preventing users from adding emails and/or phone numbers to
-their profiles.
+This configuration would disable 3PID sessions altogether, preventing users from validating emails and/or phone numbers
+and any subsequent actions that requires them, like adding them to their profiles.
+
This would be used if mxisd is also performing authentication for the Homeserver, typically with synapse and the
-[REST password provider](https://github.com/kamax-io/matrix-synapse-rest-auth).
-
-**This mode comes with several important restrictions:**
-- This does not prevent users from removing 3PID from their profile. They would be unable to add them back!
-- This prevents users from initiating remote session to make their 3PID binds globally visible
-
-It is therefore recommended to not fully disable sessions but instead restrict specific set of 3PID and Session scopes.
+[REST password provider](https://github.com/kamax-matrix/matrix-synapse-rest-auth), where 3PID mappings would be
+auto-populated.
Use the following values to enable this mode:
```yaml
diff --git a/src/main/java/io/kamax/mxisd/HttpMxisd.java b/src/main/java/io/kamax/mxisd/HttpMxisd.java
index 2b7f270..7ecb054 100644
--- a/src/main/java/io/kamax/mxisd/HttpMxisd.java
+++ b/src/main/java/io/kamax/mxisd/HttpMxisd.java
@@ -86,8 +86,6 @@ public class HttpMxisd {
.get(SessionTpidGetValidatedHandler.Path, SaneHandler.around(new SessionTpidGetValidatedHandler(m.getSession())))
.post(SessionTpidBindHandler.Path, SaneHandler.around(new SessionTpidBindHandler(m.getSession(), m.getInvitationManager())))
.post(SessionTpidUnbindHandler.Path, SaneHandler.around(new SessionTpidUnbindHandler(m.getSession())))
- .get(RemoteIdentityAPIv1.SESSION_REQUEST_TOKEN, SaneHandler.around(new RemoteSessionStartHandler(m.getSession(), m.getConfig().getView())))
- .get(RemoteIdentityAPIv1.SESSION_CHECK, SaneHandler.around(new RemoteSessionCheckHandler(m.getSession(), m.getConfig().getView())))
// Profile endpoints
.get(ProfileHandler.Path, SaneHandler.around(new ProfileHandler(m.getProfile())))
diff --git a/src/main/java/io/kamax/mxisd/Mxisd.java b/src/main/java/io/kamax/mxisd/Mxisd.java
index 0d8dbac..6d1c14b 100644
--- a/src/main/java/io/kamax/mxisd/Mxisd.java
+++ b/src/main/java/io/kamax/mxisd/Mxisd.java
@@ -45,7 +45,7 @@ import io.kamax.mxisd.notification.NotificationHandlers;
import io.kamax.mxisd.notification.NotificationManager;
import io.kamax.mxisd.profile.ProfileManager;
import io.kamax.mxisd.profile.ProfileProviders;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.kamax.mxisd.storage.IStorage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqlStorage;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -72,7 +72,7 @@ public class Mxisd {
protected InvitationManager invMgr;
protected ProfileManager pMgr;
protected AppSvcManager asHander;
- protected SessionMananger sessMgr;
+ protected SessionManager sessMgr;
protected NotificationManager notifMgr;
public Mxisd(MxisdConfig cfg) {
@@ -102,7 +102,7 @@ public class Mxisd {
idStrategy = new RecursivePriorityLookupStrategy(cfg.getLookup(), ThreePidProviders.get(), bridgeFetcher);
pMgr = new ProfileManager(ProfileProviders.get(), clientDns, httpClient);
notifMgr = new NotificationManager(cfg.getNotification(), NotificationHandlers.get());
- sessMgr = new SessionMananger(cfg.getSession(), cfg.getMatrix(), store, notifMgr, idStrategy, httpClient);
+ sessMgr = new SessionManager(cfg.getSession(), cfg.getMatrix(), store, notifMgr, idStrategy, httpClient);
invMgr = new InvitationManager(cfg.getInvite(), store, idStrategy, signMgr, fedDns, notifMgr);
authMgr = new AuthManager(cfg, AuthProviders.get(), idStrategy, invMgr, clientDns, httpClient);
dirMgr = new DirectoryManager(cfg.getDirectory(), clientDns, httpClient, DirectoryProviders.get());
@@ -137,7 +137,7 @@ public class Mxisd {
return authMgr;
}
- public SessionMananger getSession() {
+ public SessionManager getSession() {
return sessMgr;
}
diff --git a/src/main/java/io/kamax/mxisd/config/SessionConfig.java b/src/main/java/io/kamax/mxisd/config/SessionConfig.java
index 8f0af91..ae9a0f7 100644
--- a/src/main/java/io/kamax/mxisd/config/SessionConfig.java
+++ b/src/main/java/io/kamax/mxisd/config/SessionConfig.java
@@ -32,68 +32,7 @@ public class SessionConfig {
public static class PolicyTemplate {
- public static class PolicySource {
-
- public static class PolicySourceRemote {
-
- private boolean enabled;
- private String server;
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public String getServer() {
- return server;
- }
-
- public void setServer(String server) {
- this.server = server;
- }
-
- }
-
- private boolean enabled;
- private boolean toLocal;
- private PolicySourceRemote toRemote = new PolicySourceRemote();
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public boolean toLocal() {
- return toLocal;
- }
-
- public void setToLocal(boolean toLocal) {
- this.toLocal = toLocal;
- }
-
- public boolean toRemote() {
- return toRemote.isEnabled();
- }
-
- public PolicySourceRemote getToRemote() {
- return toRemote;
- }
-
- public void setToRemote(PolicySourceRemote toRemote) {
- this.toRemote = toRemote;
- }
-
- }
-
private boolean enabled;
- private PolicySource forLocal = new PolicySource();
- private PolicySource forRemote = new PolicySource();
public boolean isEnabled() {
return enabled;
@@ -103,26 +42,6 @@ public class SessionConfig {
this.enabled = enabled;
}
- public PolicySource getForLocal() {
- return forLocal;
- }
-
- public PolicySource forLocal() {
- return forLocal;
- }
-
- public PolicySource getForRemote() {
- return forRemote;
- }
-
- public PolicySource forRemote() {
- return forRemote;
- }
-
- public PolicySource forIf(boolean isLocal) {
- return isLocal ? forLocal : forRemote;
- }
-
}
public static class PolicyUnbind {
@@ -155,15 +74,6 @@ public class SessionConfig {
public Policy() {
validation.enabled = true;
- validation.forLocal.enabled = true;
- validation.forLocal.toLocal = true;
- validation.forLocal.toRemote.enabled = true;
- validation.forLocal.toRemote.server = "matrix-org";
-
- validation.forRemote.enabled = true;
- validation.forRemote.toLocal = false;
- validation.forRemote.toRemote.enabled = true;
- validation.forRemote.toRemote.server = "matrix-org";
}
private PolicyTemplate validation = new PolicyTemplate();
diff --git a/src/main/java/io/kamax/mxisd/config/ViewConfig.java b/src/main/java/io/kamax/mxisd/config/ViewConfig.java
index dc5b005..b07282e 100644
--- a/src/main/java/io/kamax/mxisd/config/ViewConfig.java
+++ b/src/main/java/io/kamax/mxisd/config/ViewConfig.java
@@ -21,12 +21,13 @@
package io.kamax.mxisd.config;
import io.kamax.matrix.json.GsonUtil;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ViewConfig {
- private transient final Logger log = LoggerFactory.getLogger(ViewConfig.class);
+ private static final Logger log = LoggerFactory.getLogger(ViewConfig.class);
public static class Session {
@@ -67,45 +68,13 @@ public class ViewConfig {
}
- public static class Remote {
-
- private Paths onRequest = new Paths();
- private Paths onCheck = new Paths();
-
- public Paths getOnRequest() {
- return onRequest;
- }
-
- public void setOnRequest(Paths onRequest) {
- this.onRequest = onRequest;
- }
-
- public Paths getOnCheck() {
- return onCheck;
- }
-
- public void setOnCheck(Paths onCheck) {
- this.onCheck = onCheck;
- }
-
- }
-
+ // Legacy option
private Local local = new Local();
- private Local localRemote = new Local();
- private Remote remote = new Remote();
+ private Paths onTokenSubmit = new Paths();
public Session() {
- local.onTokenSubmit.success = "classpath:/templates/session/local/tokenSubmitSuccess.html";
- local.onTokenSubmit.failure = "classpath:/templates/session/local/tokenSubmitFailure.html";
-
- localRemote.onTokenSubmit.success = "classpath:/templates/session/localRemote/tokenSubmitSuccess.html";
- localRemote.onTokenSubmit.failure = "classpath:/templates/session/local/tokenSubmitFailure.html";
-
- remote.onRequest.success = "classpath:/templates/session/remote/requestSuccess.html";
- remote.onRequest.failure = "classpath:/templates/session/remote/requestFailure.html";
-
- remote.onCheck.success = "classpath:/templates/session/remote/checkSuccess.html";
- remote.onCheck.failure = "classpath:/templates/session/remote/checkFailure.html";
+ onTokenSubmit.success = "classpath:/templates/session/tokenSubmitSuccess.html";
+ onTokenSubmit.failure = "classpath:/templates/session/tokenSubmitFailure.html";
}
public Local getLocal() {
@@ -116,21 +85,14 @@ public class ViewConfig {
this.local = local;
}
- public Local getLocalRemote() {
- return localRemote;
+ public Paths getOnTokenSubmit() {
+ return onTokenSubmit;
}
- public void setLocalRemote(Local localRemote) {
- this.localRemote = localRemote;
+ public void setOnTokenSubmit(Paths onTokenSubmit) {
+ this.onTokenSubmit = onTokenSubmit;
}
- public Remote getRemote() {
- return remote;
- }
-
- public void setRemote(Remote remote) {
- this.remote = remote;
- }
}
private Session session = new Session();
@@ -144,6 +106,17 @@ public class ViewConfig {
}
public void build() {
+ if (StringUtils.isNotBlank(session.local.onTokenSubmit.success) && StringUtils.isBlank(session.onTokenSubmit.success)) {
+ log.warn("Legacy option session.local.onTokenSubmit.success in use, please switch to session.onTokenSubmit.success");
+ session.onTokenSubmit.success = session.local.onTokenSubmit.success;
+ }
+
+ if (StringUtils.isNotBlank(session.local.onTokenSubmit.failure) && StringUtils.isBlank(session.onTokenSubmit.failure)) {
+ log.warn("Legacy option session.local.onTokenSubmit.failure in use, please switch to session.onTokenSubmit.failure");
+ session.onTokenSubmit.failure = session.local.onTokenSubmit.failure;
+ }
+
+
log.info("--- View config ---");
log.info("Session: {}", GsonUtil.get().toJson(session));
}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java
deleted file mode 100644
index 71bd4ff..0000000
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * mxisd - Matrix Identity Server Daemon
- * Copyright (C) 2017 Kamax Sarl
- *
- * https://www.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 .
- */
-
-package io.kamax.mxisd.http.undertow.handler.identity.v1;
-
-public class RemoteIdentityAPIv1 {
-
- public static final String BASE = "/_matrix/identity/remote/api/v1";
- public static final String SESSION_REQUEST_TOKEN = BASE + "/validate/requestToken";
- public static final String SESSION_CHECK = BASE + "/validate/check";
-
- public static String getRequestToken(String id, String secret) {
- return SESSION_REQUEST_TOKEN + "?sid=" + id + "&client_secret=" + secret;
- }
-
- public static String getSessionCheck(String id, String secret) {
- return SESSION_CHECK + "?sid=" + id + "&client_secret=" + secret;
- }
-
-}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionCheckHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionCheckHandler.java
deleted file mode 100644
index 33800f1..0000000
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionCheckHandler.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * mxisd - Matrix Identity Server Daemon
- * Copyright (C) 2018 Kamax Sarl
- *
- * https://www.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 .
- */
-
-package io.kamax.mxisd.http.undertow.handler.identity.v1;
-
-import io.kamax.mxisd.config.ViewConfig;
-import io.kamax.mxisd.exception.SessionNotValidatedException;
-import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
-import io.kamax.mxisd.session.SessionMananger;
-import io.kamax.mxisd.util.FileUtil;
-import io.undertow.server.HttpServerExchange;
-
-public class RemoteSessionCheckHandler extends BasicHttpHandler {
-
- private SessionMananger mgr;
- private ViewConfig viewCfg;
-
- public RemoteSessionCheckHandler(SessionMananger mgr, ViewConfig viewCfg) {
- this.mgr = mgr;
- this.viewCfg = viewCfg;
- }
-
- @Override
- public void handleRequest(HttpServerExchange exchange) throws Exception {
- String sid = getQueryParameter(exchange, "sid");
- String secret = getQueryParameter(exchange, "client_secret");
-
- String viewData;
- try {
- mgr.validateRemote(sid, secret);
- viewData = FileUtil.load(viewCfg.getSession().getRemote().getOnCheck().getSuccess());
- } catch (SessionNotValidatedException e) {
- viewData = FileUtil.load(viewCfg.getSession().getRemote().getOnCheck().getFailure());
- }
-
- writeBodyAsUtf8(exchange, viewData);
- }
-
-}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionStartHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionStartHandler.java
deleted file mode 100644
index 9e50fe3..0000000
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionStartHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * mxisd - Matrix Identity Server Daemon
- * Copyright (C) 2018 Kamax Sarl
- *
- * https://www.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 .
- */
-
-package io.kamax.mxisd.http.undertow.handler.identity.v1;
-
-import io.kamax.mxisd.config.ViewConfig;
-import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
-import io.kamax.mxisd.session.SessionMananger;
-import io.kamax.mxisd.threepid.session.IThreePidSession;
-import io.kamax.mxisd.util.FileUtil;
-import io.undertow.server.HttpServerExchange;
-
-public class RemoteSessionStartHandler extends BasicHttpHandler {
-
- private SessionMananger mgr;
- private ViewConfig viewCfg;
-
- public RemoteSessionStartHandler(SessionMananger mgr, ViewConfig viewCfg) {
- this.mgr = mgr;
- this.viewCfg = viewCfg;
- }
-
- @Override
- public void handleRequest(HttpServerExchange exchange) throws Exception {
- String sid = getQueryParameter(exchange, "sid");
- String secret = getQueryParameter(exchange, "client_secret");
- IThreePidSession session = mgr.createRemote(sid, secret);
-
- String rawData = FileUtil.load(viewCfg.getSession().getRemote().getOnRequest().getSuccess());
- String data = rawData.replace("${checkLink}", RemoteIdentityAPIv1.getSessionCheck(session.getId(), session.getSecret()));
- writeBodyAsUtf8(exchange, data);
- }
-
-}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionStartHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionStartHandler.java
index a8446ae..0d60020 100644
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionStartHandler.java
+++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionStartHandler.java
@@ -28,7 +28,7 @@ import io.kamax.mxisd.http.io.identity.RequestTokenResponse;
import io.kamax.mxisd.http.io.identity.SessionEmailTokenRequestJson;
import io.kamax.mxisd.http.io.identity.SessionPhoneTokenRequestJson;
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.undertow.server.HttpServerExchange;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
@@ -41,9 +41,9 @@ public class SessionStartHandler extends BasicHttpHandler {
private transient final Logger log = LoggerFactory.getLogger(SessionStartHandler.class);
- private SessionMananger mgr;
+ private SessionManager mgr;
- public SessionStartHandler(SessionMananger mgr) {
+ public SessionStartHandler(SessionManager mgr) {
this.mgr = mgr;
}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidBindHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidBindHandler.java
index 943f518..80ce3ac 100644
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidBindHandler.java
+++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidBindHandler.java
@@ -26,7 +26,7 @@ import io.kamax.mxisd.http.IsAPIv1;
import io.kamax.mxisd.http.io.identity.BindRequest;
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
import io.kamax.mxisd.invitation.InvitationManager;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.QueryParameterUtils;
import org.apache.commons.lang.StringUtils;
@@ -44,10 +44,10 @@ public class SessionTpidBindHandler extends BasicHttpHandler {
private transient final Logger log = LoggerFactory.getLogger(SessionTpidBindHandler.class);
- private SessionMananger mgr;
+ private SessionManager mgr;
private InvitationManager invMgr;
- public SessionTpidBindHandler(SessionMananger mgr, InvitationManager invMgr) {
+ public SessionTpidBindHandler(SessionManager mgr, InvitationManager invMgr) {
this.mgr = mgr;
this.invMgr = invMgr;
}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidGetValidatedHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidGetValidatedHandler.java
index 8c1e003..98ee164 100644
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidGetValidatedHandler.java
+++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidGetValidatedHandler.java
@@ -25,7 +25,7 @@ import io.kamax.mxisd.exception.SessionNotValidatedException;
import io.kamax.mxisd.http.IsAPIv1;
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
import io.kamax.mxisd.lookup.ThreePidValidation;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.undertow.server.HttpServerExchange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,11 +34,11 @@ public class SessionTpidGetValidatedHandler extends BasicHttpHandler {
public static final String Path = IsAPIv1.Base + "/3pid/getValidated3pid";
- private transient final Logger log = LoggerFactory.getLogger(SessionTpidGetValidatedHandler.class);
+ private static final Logger log = LoggerFactory.getLogger(SessionTpidGetValidatedHandler.class);
- private SessionMananger mgr;
+ private SessionManager mgr;
- public SessionTpidGetValidatedHandler(SessionMananger mgr) {
+ public SessionTpidGetValidatedHandler(SessionManager mgr) {
this.mgr = mgr;
}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidUnbindHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidUnbindHandler.java
index 4cdd05a..bc43a44 100644
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidUnbindHandler.java
+++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidUnbindHandler.java
@@ -23,27 +23,23 @@ package io.kamax.mxisd.http.undertow.handler.identity.v1;
import com.google.gson.JsonObject;
import io.kamax.mxisd.http.IsAPIv1;
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.undertow.server.HttpServerExchange;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class SessionTpidUnbindHandler extends BasicHttpHandler {
public static final String Path = IsAPIv1.Base + "/3pid/unbind";
- private static final Logger log = LoggerFactory.getLogger(SessionTpidUnbindHandler.class);
+ private final SessionManager sessionMgr;
- private final SessionMananger sessMgr;
-
- public SessionTpidUnbindHandler(SessionMananger sessMgr) {
- this.sessMgr = sessMgr;
+ public SessionTpidUnbindHandler(SessionManager sessionMgr) {
+ this.sessionMgr = sessionMgr;
}
@Override
public void handleRequest(HttpServerExchange exchange) {
JsonObject body = parseJsonObject(exchange);
- sessMgr.unbind(body);
+ sessionMgr.unbind(body);
writeBodyAsUtf8(exchange, "{}");
}
diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionValidateHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionValidateHandler.java
index f981f21..589d904 100644
--- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionValidateHandler.java
+++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionValidateHandler.java
@@ -25,7 +25,7 @@ import io.kamax.mxisd.config.ViewConfig;
import io.kamax.mxisd.http.IsAPIv1;
import io.kamax.mxisd.http.io.identity.SuccessStatusJson;
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
-import io.kamax.mxisd.session.SessionMananger;
+import io.kamax.mxisd.session.SessionManager;
import io.kamax.mxisd.session.ValidationResult;
import io.kamax.mxisd.util.FileUtil;
import io.undertow.server.HttpServerExchange;
@@ -44,11 +44,11 @@ public class SessionValidateHandler extends BasicHttpHandler {
private transient final Logger log = LoggerFactory.getLogger(SessionValidateHandler.class);
- private SessionMananger mgr;
+ private SessionManager mgr;
private ServerConfig srvCfg;
private ViewConfig viewCfg;
- public SessionValidateHandler(SessionMananger mgr, ServerConfig srvCfg, ViewConfig viewCfg) {
+ public SessionValidateHandler(SessionManager mgr, ServerConfig srvCfg, ViewConfig viewCfg) {
this.mgr = mgr;
this.srvCfg = srvCfg;
this.viewCfg = viewCfg;
@@ -72,11 +72,11 @@ public class SessionValidateHandler extends BasicHttpHandler {
if (isHtmlRequest) {
handleHtmlRequest(exchange, medium, sid, secret, token);
} else {
- handleJsonRequest(exchange, medium, sid, secret, token);
+ handleJsonRequest(exchange, sid, secret, token);
}
}
- public void handleHtmlRequest(HttpServerExchange exchange, String medium, String sid, String secret, String token) {
+ private void handleHtmlRequest(HttpServerExchange exchange, String medium, String sid, String secret, String token) {
log.info("Validating session {} for medium {}", sid, medium);
ValidationResult r = mgr.validate(sid, secret, token);
log.info("Session {} was validated", sid);
@@ -93,24 +93,18 @@ public class SessionValidateHandler extends BasicHttpHandler {
exchange.getResponseHeaders().add(HttpString.tryFromString("Location"), url);
} else {
try {
- String rawData = FileUtil.load(viewCfg.getSession().getLocalRemote().getOnTokenSubmit().getSuccess());
- if (r.isCanRemote()) {
- String url = srvCfg.getPublicUrl() + RemoteIdentityAPIv1.getRequestToken(r.getSession().getId(), r.getSession().getSecret());
- String data = rawData.replace("${remoteSessionLink}", url);
- writeBodyAsUtf8(exchange, data);
- } else {
- writeBodyAsUtf8(exchange, rawData);
- }
+ String data = FileUtil.load(viewCfg.getSession().getOnTokenSubmit().getSuccess());
+ writeBodyAsUtf8(exchange, data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
- public void handleJsonRequest(HttpServerExchange exchange, String medium, String sid, String secret, String token) {
+ private void handleJsonRequest(HttpServerExchange exchange, String sid, String secret, String token) {
log.info("Requested: {}", exchange.getRequestURL());
- ValidationResult r = mgr.validate(sid, secret, token);
+ mgr.validate(sid, secret, token);
log.info("Session {} was validated", sid);
respondJson(exchange, new SuccessStatusJson(true));
diff --git a/src/main/java/io/kamax/mxisd/session/SessionManager.java b/src/main/java/io/kamax/mxisd/session/SessionManager.java
new file mode 100644
index 0000000..678e737
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/session/SessionManager.java
@@ -0,0 +1,228 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2017 Kamax Sarl
+ *
+ * https://www.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 .
+ */
+
+package io.kamax.mxisd.session;
+
+import com.google.gson.JsonObject;
+import io.kamax.matrix.MatrixID;
+import io.kamax.matrix.ThreePid;
+import io.kamax.matrix._MatrixID;
+import io.kamax.matrix.json.GsonUtil;
+import io.kamax.mxisd.config.MatrixConfig;
+import io.kamax.mxisd.config.SessionConfig;
+import io.kamax.mxisd.exception.NotAllowedException;
+import io.kamax.mxisd.exception.NotImplementedException;
+import io.kamax.mxisd.exception.SessionNotValidatedException;
+import io.kamax.mxisd.exception.SessionUnknownException;
+import io.kamax.mxisd.lookup.SingleLookupReply;
+import io.kamax.mxisd.lookup.ThreePidValidation;
+import io.kamax.mxisd.lookup.strategy.LookupStrategy;
+import io.kamax.mxisd.notification.NotificationManager;
+import io.kamax.mxisd.storage.IStorage;
+import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
+import io.kamax.mxisd.threepid.session.ThreePidSession;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+import static io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate;
+
+public class SessionManager {
+
+ private static final Logger log = LoggerFactory.getLogger(SessionManager.class);
+
+ private SessionConfig cfg;
+ private MatrixConfig mxCfg;
+ private IStorage storage;
+ private NotificationManager notifMgr;
+ private LookupStrategy lookupMgr;
+
+ // FIXME export into central class, set version
+ private CloseableHttpClient client;
+
+ public SessionManager(
+ SessionConfig cfg,
+ MatrixConfig mxCfg,
+ IStorage storage,
+ NotificationManager notifMgr,
+ LookupStrategy lookupMgr,
+ CloseableHttpClient client
+ ) {
+ this.cfg = cfg;
+ this.mxCfg = mxCfg;
+ this.storage = storage;
+ this.notifMgr = notifMgr;
+ this.lookupMgr = lookupMgr;
+ this.client = client;
+ }
+
+ private ThreePidSession getSession(String sid, String secret) {
+ Optional dao = storage.getThreePidSession(sid);
+ if (!dao.isPresent() || !StringUtils.equals(dao.get().getSecret(), secret)) {
+ throw new SessionUnknownException();
+ }
+
+ return new ThreePidSession(dao.get());
+ }
+
+ private ThreePidSession getSessionIfValidated(String sid, String secret) {
+ ThreePidSession session = getSession(sid, secret);
+ if (!session.isValidated()) {
+ throw new SessionNotValidatedException();
+ }
+ return session;
+ }
+
+ public String create(String server, ThreePid tpid, String secret, int attempt, String nextLink) {
+ PolicyTemplate policy = cfg.getPolicy().getValidation();
+ if (!policy.isEnabled()) {
+ throw new NotAllowedException("Validating 3PID is disabled");
+ }
+
+ synchronized (this) {
+ log.info("Server {} is asking to create session for {} (Attempt #{}) - Next link: {}", server, tpid, attempt, nextLink);
+ Optional dao = storage.findThreePidSession(tpid, secret);
+ if (dao.isPresent()) {
+ ThreePidSession session = new ThreePidSession(dao.get());
+ log.info("We already have a session for {}: {}", tpid, session.getId());
+ if (session.getAttempt() < attempt) {
+ log.info("Received attempt {} is greater than stored attempt {}, sending validation communication", attempt, session.getAttempt());
+ notifMgr.sendForValidation(session);
+ log.info("Sent validation notification to {}", tpid);
+ session.increaseAttempt();
+ storage.updateThreePidSession(session.getDao());
+ }
+
+ return session.getId();
+ } else {
+ log.info("No existing session for {}", tpid);
+
+ String sessionId;
+ do {
+ sessionId = Long.toString(System.currentTimeMillis());
+ } while (storage.getThreePidSession(sessionId).isPresent());
+
+ String token = RandomStringUtils.randomNumeric(6);
+ ThreePidSession session = new ThreePidSession(sessionId, server, tpid, secret, attempt, nextLink, token);
+ log.info("Generated new session {} to validate {} from server {}", sessionId, tpid, server);
+
+ storage.insertThreePidSession(session.getDao());
+ log.info("Stored session {}", sessionId, tpid, server);
+
+ log.info("Session {} for {}: sending validation notification", sessionId, tpid);
+ notifMgr.sendForValidation(session);
+
+ return sessionId;
+ }
+ }
+ }
+
+ public ValidationResult validate(String sid, String secret, String token) {
+ ThreePidSession session = getSession(sid, secret);
+ log.info("Attempting validation for session {} from {}", session.getId(), session.getServer());
+
+ session.validate(token);
+ storage.updateThreePidSession(session.getDao());
+ log.info("Session {} has been validated locally", session.getId());
+
+ ValidationResult r = new ValidationResult(session);
+ session.getNextLink().ifPresent(r::setNextUrl);
+ return r;
+ }
+
+ public ThreePidValidation getValidated(String sid, String secret) {
+ ThreePidSession session = getSessionIfValidated(sid, secret);
+ return new ThreePidValidation(session.getThreePid(), session.getValidationTime());
+ }
+
+ public void bind(String sid, String secret, String mxidRaw) {
+ // We make sure we have an acceptable User ID
+ if (StringUtils.isEmpty(mxidRaw)) {
+ throw new IllegalArgumentException("No Matrix User ID provided");
+ }
+
+ // We ensure the session was validated
+ ThreePidSession session = getSessionIfValidated(sid, secret);
+
+ // We parse the Matrix ID as acceptable
+ _MatrixID mxid = MatrixID.asAcceptable(mxidRaw);
+
+ // Only accept binds if the domain matches our own
+ if (!StringUtils.equalsIgnoreCase(mxCfg.getDomain(), mxid.getDomain())) {
+ throw new NotAllowedException("Only Matrix IDs from domain " + mxCfg + " can be bound");
+ }
+
+ log.info("Session {}: Binding of {}:{} to Matrix ID {} is accepted",
+ session.getId(), session.getThreePid().getMedium(), session.getThreePid().getAddress(), mxid.getId());
+ }
+
+ public void unbind(JsonObject reqData) {
+ // TODO also check for HS header to know which domain attempting the unbind
+ if (reqData.entrySet().size() == 2 && reqData.has("mxid") && reqData.has("threepid")) {
+ /* This is a HS request to remove a 3PID and is considered:
+ * - An attack on user privacy
+ * - A baffling spec breakage requiring IS and HS 3PID info to be independent [1]
+ * - A baffling spec breakage that 3PID (un)bind is only one way [2]
+ *
+ * Given the lack of response on our extensive feedback on the proposal [3] which has not landed in the spec yet [4],
+ * We'll be denying such unbind requests and will inform users using their 3PID that a fraudulent attempt of
+ * removing their 3PID binding has been attempted and blocked.
+ *
+ * [1]: https://matrix.org/docs/spec/client_server/r0.4.0.html#adding-account-administrative-contact-information
+ * [2]: https://matrix.org/docs/spec/identity_service/r0.1.0.html#privacy
+ * [3]: https://docs.google.com/document/d/135g2muVxmuml0iUnLoTZxk8M2ZSt3kJzg81chGh51yg/edit
+ * [4]: https://github.com/matrix-org/matrix-doc/issues/1194
+ */
+
+ log.warn("A remote host attempted to unbind without proper authorization. Request was denied");
+
+ if (!cfg.getPolicy().getUnbind().getFraudulent().getSendWarning()) {
+ log.info("Not sending notification to 3PID owner as per configuration");
+ } else {
+ log.info("Sending notification to 3PID owner as per configuration");
+
+ ThreePid tpid = GsonUtil.get().fromJson(GsonUtil.getObj(reqData, "threepid"), ThreePid.class);
+ Optional lookup = lookupMgr.findLocal(tpid.getMedium(), tpid.getAddress());
+ if (!lookup.isPresent()) {
+ log.info("No 3PID owner found, not sending any notification");
+ } else {
+ log.info("3PID owner found, sending notification");
+ try {
+ notifMgr.sendForFraudulentUnbind(tpid);
+ log.info("Notification sent");
+ } catch (NotImplementedException e) {
+ log.warn("Unable to send notification: {}", e.getMessage());
+ } catch (RuntimeException e) {
+ log.warn("Unable to send notification due to unknown error. See stacktrace below", e);
+ }
+ }
+ }
+ }
+
+ log.info("Denying request");
+ throw new NotAllowedException("You have attempted to alter 3PID bindings, which can only be done by the 3PID owner directly. " +
+ "We have informed the 3PID owner of your fraudulent attempt.");
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/session/SessionMananger.java b/src/main/java/io/kamax/mxisd/session/SessionMananger.java
deleted file mode 100644
index b0b51a5..0000000
--- a/src/main/java/io/kamax/mxisd/session/SessionMananger.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * mxisd - Matrix Identity Server Daemon
- * Copyright (C) 2017 Kamax Sarl
- *
- * https://www.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 .
- */
-
-package io.kamax.mxisd.session;
-
-import com.google.gson.JsonObject;
-import com.google.i18n.phonenumbers.NumberParseException;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
-import com.google.i18n.phonenumbers.Phonenumber;
-import io.kamax.matrix.MatrixID;
-import io.kamax.matrix.ThreePid;
-import io.kamax.matrix.ThreePidMedium;
-import io.kamax.matrix._MatrixID;
-import io.kamax.matrix.json.GsonUtil;
-import io.kamax.mxisd.config.MatrixConfig;
-import io.kamax.mxisd.config.SessionConfig;
-import io.kamax.mxisd.exception.*;
-import io.kamax.mxisd.http.io.identity.RequestTokenResponse;
-import io.kamax.mxisd.http.undertow.handler.identity.v1.RemoteIdentityAPIv1;
-import io.kamax.mxisd.lookup.SingleLookupReply;
-import io.kamax.mxisd.lookup.ThreePidValidation;
-import io.kamax.mxisd.lookup.strategy.LookupStrategy;
-import io.kamax.mxisd.matrix.IdentityServerUtils;
-import io.kamax.mxisd.notification.NotificationManager;
-import io.kamax.mxisd.storage.IStorage;
-import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
-import io.kamax.mxisd.threepid.session.IThreePidSession;
-import io.kamax.mxisd.threepid.session.ThreePidSession;
-import io.kamax.mxisd.util.GsonParser;
-import io.kamax.mxisd.util.RestClientUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-import static io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate;
-import static io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource;
-
-public class SessionMananger {
-
- private transient final Logger log = LoggerFactory.getLogger(SessionMananger.class);
-
- private SessionConfig cfg;
- private MatrixConfig mxCfg;
- private IStorage storage;
- private NotificationManager notifMgr;
- private LookupStrategy lookupMgr;
-
- private GsonParser parser = new GsonParser();
- private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); // FIXME refactor for sessions handling their own stuff
-
- // FIXME export into central class, set version
- private CloseableHttpClient client;
-
- public SessionMananger(
- SessionConfig cfg,
- MatrixConfig mxCfg,
- IStorage storage,
- NotificationManager notifMgr,
- LookupStrategy lookupMgr,
- CloseableHttpClient client
- ) {
- this.cfg = cfg;
- this.mxCfg = mxCfg;
- this.storage = storage;
- this.notifMgr = notifMgr;
- this.lookupMgr = lookupMgr;
- this.client = client;
- }
-
- private boolean isLocal(ThreePid tpid) {
- if (!ThreePidMedium.Email.is(tpid.getMedium())) { // We can only handle E-mails for now
- return false;
- }
-
- String domain = tpid.getAddress().split("@")[1];
- return StringUtils.equalsIgnoreCase(mxCfg.getDomain(), domain);
- }
-
- private ThreePidSession getSession(String sid, String secret) {
- Optional dao = storage.getThreePidSession(sid);
- if (!dao.isPresent() || !StringUtils.equals(dao.get().getSecret(), secret)) {
- throw new SessionUnknownException();
- }
-
- return new ThreePidSession(dao.get());
- }
-
- private ThreePidSession getSessionIfValidated(String sid, String secret) {
- ThreePidSession session = getSession(sid, secret);
- if (!session.isValidated()) {
- throw new SessionNotValidatedException();
- }
- return session;
- }
-
- public String create(String server, ThreePid tpid, String secret, int attempt, String nextLink) {
- PolicyTemplate policy = cfg.getPolicy().getValidation();
- if (!policy.isEnabled()) {
- throw new NotAllowedException("Validating 3PID is disabled globally");
- }
-
- synchronized (this) {
- log.info("Server {} is asking to create session for {} (Attempt #{}) - Next link: {}", server, tpid, attempt, nextLink);
- Optional dao = storage.findThreePidSession(tpid, secret);
- if (dao.isPresent()) {
- ThreePidSession session = new ThreePidSession(dao.get());
- log.info("We already have a session for {}: {}", tpid, session.getId());
- if (session.getAttempt() < attempt) {
- log.info("Received attempt {} is greater than stored attempt {}, sending validation communication", attempt, session.getAttempt());
- notifMgr.sendForValidation(session);
- log.info("Sent validation notification to {}", tpid);
- session.increaseAttempt();
- storage.updateThreePidSession(session.getDao());
- }
-
- return session.getId();
- } else {
- log.info("No existing session for {}", tpid);
-
- boolean isLocal = isLocal(tpid);
- log.info("Is 3PID bound to local domain? {}", isLocal);
-
- // This might need a configuration by medium type?
- 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;
- do {
- sessionId = Long.toString(System.currentTimeMillis());
- } while (storage.getThreePidSession(sessionId).isPresent());
-
- String token = RandomStringUtils.randomNumeric(6);
- ThreePidSession session = new ThreePidSession(sessionId, server, tpid, secret, attempt, nextLink, token);
- log.info("Generated new session {} to validate {} from server {}", sessionId, tpid, server);
-
- // This might need a configuration by medium type?
- 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());
- log.info("Stored session {}", sessionId, tpid, server);
-
- return sessionId;
- }
- }
- }
-
- public ValidationResult validate(String sid, String secret, String token) {
- ThreePidSession session = getSession(sid, secret);
- log.info("Attempting validation for session {} from {}", session.getId(), session.getServer());
-
- boolean isLocal = isLocal(session.getThreePid());
- PolicySource policy = cfg.getPolicy().getValidation().forIf(isLocal);
- if (!policy.isEnabled()) {
- throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
- }
-
- if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium()) && session.isValidated() && session.isRemote()) {
- submitRemote(session, token);
- session.validateRemote();
- return new ValidationResult(session, false);
- }
-
- session.validate(token);
- storage.updateThreePidSession(session.getDao());
- log.info("Session {} has been validated locally", session.getId());
-
- if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium()) && session.isValidated() && policy.toRemote()) {
- createRemote(sid, secret);
- // FIXME make the message configurable/customizable (templates?)
- throw new MessageForClientException("You will receive a NEW code from another number. Enter it below");
- }
-
- // FIXME definitely doable in a nicer way
- ValidationResult r = new ValidationResult(session, policy.toRemote());
- if (!policy.toLocal()) {
- r.setNextUrl(RemoteIdentityAPIv1.getRequestToken(sid, secret));
- } else {
- session.getNextLink().ifPresent(r::setNextUrl);
- }
- return r;
- }
-
- public ThreePidValidation getValidated(String sid, String secret) {
- ThreePidSession session = getSessionIfValidated(sid, secret);
- return new ThreePidValidation(session.getThreePid(), session.getValidationTime());
- }
-
- public void bind(String sid, String secret, String mxidRaw) {
- if (StringUtils.isEmpty(mxidRaw)) {
- throw new IllegalArgumentException("No Matrix User ID provided");
- }
-
- _MatrixID mxid = MatrixID.asAcceptable(mxidRaw);
- ThreePidSession session = getSessionIfValidated(sid, secret);
-
- if (!session.isRemote()) {
- log.info("Session {} for {}: MXID {} was bound locally", sid, session.getThreePid(), mxid);
- return;
- }
-
- log.info("Session {} for {}: MXID {} bind is remote", sid, session.getThreePid(), mxid);
- if (!session.isRemoteValidated()) {
- log.error("Session {} for {}: Not validated remotely", sid, session.getThreePid());
- throw new SessionNotValidatedException();
- }
-
- log.info("Session {} for {}: Performing remote bind", sid, session.getThreePid());
-
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
- Arrays.asList(
- new BasicNameValuePair("sid", session.getRemoteId()),
- new BasicNameValuePair("client_secret", session.getRemoteSecret()),
- new BasicNameValuePair("mxid", mxid.getId())
- ), StandardCharsets.UTF_8);
- HttpPost bindReq = new HttpPost(session.getRemoteServer() + "/_matrix/identity/api/v1/3pid/bind");
- bindReq.setEntity(entity);
-
- try (CloseableHttpResponse response = client.execute(bindReq)) {
- int status = response.getStatusLine().getStatusCode();
- if (status < 200 || status >= 300) {
- String body = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
- log.error("Session {} for {}: Remote IS {} failed when trying to bind {} for remote session {}\n{}",
- sid, session.getThreePid(), session.getRemoteServer(), mxid, session.getRemoteId(), body);
- throw new RemoteIdentityServerException(body);
- }
-
- log.error("Session {} for {}: MXID {} was bound remotely", sid, session.getThreePid(), mxid);
- } catch (IOException e) {
- log.error("Session {} for {}: I/O Error when trying to bind mxid {}", sid, session.getThreePid(), mxid);
- throw new RemoteIdentityServerException(e.getMessage());
- }
- }
-
- public void unbind(JsonObject reqData) {
- // TODO also check for HS header to know which domain attempting the unbind
- if (reqData.entrySet().size() == 2 && reqData.has("mxid") && reqData.has("threepid")) {
- /* This is a HS request to remove a 3PID and is considered:
- * - An attack on user privacy
- * - A baffling spec breakage requiring IS and HS 3PID info to be independent [1]
- * - A baffling spec breakage that 3PID (un)bind is only one way [2]
- *
- * Given the lack of response on our extensive feedback on the proposal [3] which has not landed in the spec yet [4],
- * We'll be denying such unbind requests and will inform users using their 3PID that a fraudulent attempt of
- * removing their 3PID binding has been attempted and blocked.
- *
- * [1]: https://matrix.org/docs/spec/client_server/r0.4.0.html#adding-account-administrative-contact-information
- * [2]: https://matrix.org/docs/spec/identity_service/r0.1.0.html#privacy
- * [3]: https://docs.google.com/document/d/135g2muVxmuml0iUnLoTZxk8M2ZSt3kJzg81chGh51yg/edit
- * [4]: https://github.com/matrix-org/matrix-doc/issues/1194
- */
-
- log.warn("A remote host attempted to unbind without proper authorization. Request was denied");
-
- if (!cfg.getPolicy().getUnbind().getFraudulent().getSendWarning()) {
- log.info("Not sending notification to 3PID owner as per configuration");
- } else {
- log.info("Sending notification to 3PID owner as per configuration");
-
- ThreePid tpid = GsonUtil.get().fromJson(GsonUtil.getObj(reqData, "threepid"), ThreePid.class);
- Optional lookup = lookupMgr.findLocal(tpid.getMedium(), tpid.getAddress());
- if (!lookup.isPresent()) {
- log.info("No 3PID owner found, not sending any notification");
- } else {
- log.info("3PID owner found, sending notification");
- try {
- notifMgr.sendForFraudulentUnbind(tpid);
- log.info("Notification sent");
- } catch (NotImplementedException e) {
- log.warn("Unable to send notification: {}", e.getMessage());
- } catch (RuntimeException e) {
- log.warn("Unable to send notification due to unknown error. See stacktrace below", e);
- }
- }
- }
- }
-
- log.info("Denying request");
- throw new NotAllowedException("You have attempted to alter 3PID bindings, which can only be done by the 3PID owner directly. " +
- "We have informed the 3PID owner of your fraudulent attempt.");
- }
-
- public IThreePidSession createRemote(String sid, String secret) {
- ThreePidSession session = getSessionIfValidated(sid, secret);
- log.info("Creating remote 3PID session for {} with local session [{}] to {}", session.getThreePid(), sid);
-
- boolean isLocal = isLocal(session.getThreePid());
- PolicySource policy = cfg.getPolicy().getValidation().forIf(isLocal);
- if (!policy.isEnabled() || !policy.toRemote()) {
- throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
- }
- log.info("Remote 3PID is allowed by policy");
-
- List servers = mxCfg.getIdentity().getServers(policy.getToRemote().getServer());
- if (servers.isEmpty()) {
- throw new FeatureNotAvailable("Remote 3PID sessions are enabled but server list is " +
- "misconstrued (invalid ID or empty list");
- }
-
- String is = servers.get(0);
- String url = IdentityServerUtils.findIsUrlForDomain(is).orElse(is);
- log.info("Will use IS endpoint {}", url);
-
- String remoteSecret = session.isRemote() ? session.getRemoteSecret() : RandomStringUtils.randomAlphanumeric(16);
-
- JsonObject body = new JsonObject();
- body.addProperty("client_secret", remoteSecret);
- body.addProperty(session.getThreePid().getMedium(), session.getThreePid().getAddress());
- body.addProperty("send_attempt", session.increaseAndGetRemoteAttempt());
- if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium())) {
- try {
- Phonenumber.PhoneNumber msisdn = phoneUtil.parse("+" + session.getThreePid().getAddress(), null);
- String country = phoneUtil.getRegionCodeForNumber(msisdn).toUpperCase();
- body.addProperty("phone_number", phoneUtil.format(msisdn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
- body.addProperty("country", country);
- } catch (NumberParseException e) {
- throw new InternalServerError(e);
- }
- } else {
- body.addProperty(session.getThreePid().getMedium(), session.getThreePid().getAddress());
- }
-
- log.info("Requesting remote session with attempt {}", session.getRemoteAttempt());
- HttpPost tokenReq = RestClientUtils.post(url + "/_matrix/identity/api/v1/validate/" + session.getThreePid().getMedium() + "/requestToken", body);
- try (CloseableHttpResponse response = client.execute(tokenReq)) {
- int status = response.getStatusLine().getStatusCode();
- if (status < 200 || status >= 300) {
- JsonObject obj = parser.parseOptional(response).orElseThrow(() -> new RemoteIdentityServerException("Status " + status));
- throw new RemoteIdentityServerException(obj.get("errcode").getAsString() + ": " + obj.get("error").getAsString());
- }
-
- RequestTokenResponse data = new GsonParser().parse(response, RequestTokenResponse.class);
- log.info("Remote Session ID: {}", data.getSid());
-
- session.setRemoteData(url, data.getSid(), remoteSecret, 1);
- storage.updateThreePidSession(session.getDao());
- log.info("Updated Session {} with remote data", sid);
-
- return session;
- } catch (IOException e) {
- log.warn("Failed to create remote session with {} for {}: {}", url, session.getThreePid(), e.getMessage());
- throw new RemoteIdentityServerException(e.getMessage());
- }
- }
-
- private void submitRemote(ThreePidSession session, String token) {
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
- Arrays.asList(
- new BasicNameValuePair("sid", session.getRemoteId()),
- new BasicNameValuePair("client_secret", session.getRemoteSecret()),
- new BasicNameValuePair("token", token)
- ), StandardCharsets.UTF_8);
- HttpPost submitReq = new HttpPost(session.getRemoteServer() + "/_matrix/identity/api/v1/submitToken");
- submitReq.setEntity(entity);
-
- try (CloseableHttpResponse response = client.execute(submitReq)) {
- JsonObject o = new GsonParser().parse(response.getEntity().getContent());
- if (!o.has("success") || !o.get("success").getAsBoolean()) {
- String errcode = o.get("errcode").getAsString();
- throw new RemoteIdentityServerException(errcode + ": " + o.get("error").getAsString());
- }
-
- log.info("Successfully submitted validation token for {} to {}", session.getThreePid(), session.getRemoteServer());
- } catch (IOException e) {
- throw new RemoteIdentityServerException(e.getMessage());
- }
- }
-
- public void validateRemote(String sid, String secret) {
- ThreePidSession session = getSessionIfValidated(sid, secret);
- if (!session.isRemote()) {
- throw new NotAllowedException("Cannot remotely validate a local session");
- }
-
- log.info("Session {} for {}: Validating remote 3PID session {} on {}", sid, session.getThreePid(), session.getRemoteId(), session.getRemoteServer());
- if (session.isRemoteValidated()) {
- log.info("Session {} for {}: Already remotely validated", sid, session.getThreePid());
- return;
- }
-
- HttpGet validateReq = new HttpGet(session.getRemoteServer() + "/_matrix/identity/api/v1/3pid/getValidated3pid?sid=" + session.getRemoteId() + "&client_secret=" + session.getRemoteSecret());
- try (CloseableHttpResponse response = client.execute(validateReq)) {
- int status = response.getStatusLine().getStatusCode();
- if (status < 200 || status >= 300) {
- throw new RemoteIdentityServerException("Remote identity server returned with status " + status);
- }
-
- JsonObject o = new GsonParser().parse(response.getEntity().getContent());
- if (o.has("errcode")) {
- String errcode = o.get("errcode").getAsString();
- if (StringUtils.equals("M_SESSION_NOT_VALIDATED", errcode)) {
- throw new SessionNotValidatedException();
- } else if (StringUtils.equals("M_NO_VALID_SESSION", errcode)) {
- throw new SessionUnknownException();
- } else {
- throw new RemoteIdentityServerException("Unknown error while validating Remote 3PID session: " + errcode + " - " + o.get("error").getAsString());
- }
- }
-
- if (o.has("validated_at")) {
- ThreePid remoteThreePid = new ThreePid(o.get("medium").getAsString(), o.get("address").getAsString());
- if (!session.getThreePid().equals(remoteThreePid)) { // sanity check
- throw new InternalServerError("Local 3PID " + session.getThreePid() + " and remote 3PID " + remoteThreePid + " do not match for session " + session.getId());
- }
-
- log.info("Session {} for {}: Remotely validated successfully", sid, session.getThreePid());
- session.validateRemote();
- storage.updateThreePidSession(session.getDao());
- log.info("Session {} was updated in storage", sid);
- }
- } catch (IOException e) {
- log.warn("Session {} for {}: Failed to validated remotely on {}: {}", sid, session.getThreePid(), session.getRemoteServer(), e.getMessage());
- throw new RemoteIdentityServerException(e.getMessage());
- }
- }
-
-}
diff --git a/src/main/java/io/kamax/mxisd/session/ValidationResult.java b/src/main/java/io/kamax/mxisd/session/ValidationResult.java
index 89045c2..3109f85 100644
--- a/src/main/java/io/kamax/mxisd/session/ValidationResult.java
+++ b/src/main/java/io/kamax/mxisd/session/ValidationResult.java
@@ -27,22 +27,16 @@ import java.util.Optional;
public class ValidationResult {
private IThreePidSession session;
- private boolean canRemote;
private String nextUrl;
- public ValidationResult(IThreePidSession session, boolean canRemote) {
+ public ValidationResult(IThreePidSession session) {
this.session = session;
- this.canRemote = canRemote;
}
public IThreePidSession getSession() {
return session;
}
- public boolean isCanRemote() {
- return canRemote;
- }
-
public Optional getNextUrl() {
return Optional.ofNullable(nextUrl);
}
diff --git a/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html b/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html
deleted file mode 100644
index e2b0af7..0000000
--- a/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
- Matrix Token Verification
-
-
-
-
-
Verification successful!
-
Your email will remain private and you will only be discoverable with it on your own server, or any related
- servers configured by your system admin.
- If you would like to be globally discoverable, start the process here.
-
If you chose to start the global publication process, wait until it is done before returning to your
- client.
-
If the remote process is finished, or if you do not wish to start it at this time, you can now return to your
- Matrix client to complete the process.
-
-
-
diff --git a/src/main/resources/templates/session/remote/checkFailure.html b/src/main/resources/templates/session/remote/checkFailure.html
deleted file mode 100644
index 95965fc..0000000
--- a/src/main/resources/templates/session/remote/checkFailure.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- Matrix global token verification
-
-
-
-
-
You do not seem to have validated your session with the global server. Please check your messages for one similar
- to the one you received initially.
- Once this is done, click here to continue
-
If this problem persists, contact your system administrator with the following info: Reference #ABC
-
-
-
diff --git a/src/main/resources/templates/session/remote/checkSuccess.html b/src/main/resources/templates/session/remote/checkSuccess.html
deleted file mode 100644
index 1369763..0000000
--- a/src/main/resources/templates/session/remote/checkSuccess.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- Matrix global token verification
-
-
-
-
-
Verification successful!
-
Return to your Matrix client to complete the process and make yourself globally discoverable.
-
-
-
diff --git a/src/main/resources/templates/session/remote/requestFailure.html b/src/main/resources/templates/session/remote/requestFailure.html
deleted file mode 100644
index d546307..0000000
--- a/src/main/resources/templates/session/remote/requestFailure.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- Matrix global token verification
-
-
-
-
-
The process to be globally discoverable has failed!
You can try to refresh this page in a few seconds or
- minutes.
-
If this problem persists, contact your system administrator with the following info: Reference #ABC
-
-
-
diff --git a/src/main/resources/templates/session/remote/requestSuccess.html b/src/main/resources/templates/session/remote/requestSuccess.html
deleted file mode 100644
index fbf678b..0000000
--- a/src/main/resources/templates/session/remote/requestSuccess.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
- Matrix global token verification
-
-
-
-
-
The process to be globally discoverable has started. A verification token has been requested on your behalf.
-
You will receive a similar communication as the first verification message.
- Follow the instructions and come back to this page once you are told to return to your Matrix client or that the
- verification was successful.
-
Once the validation was successful with the global server, please follow this link
- to validate it with us.
-
-
-
diff --git a/src/main/resources/templates/session/local/tokenSubmitFailure.html b/src/main/resources/templates/session/tokenSubmitFailure.html
similarity index 100%
rename from src/main/resources/templates/session/local/tokenSubmitFailure.html
rename to src/main/resources/templates/session/tokenSubmitFailure.html
diff --git a/src/main/resources/templates/session/local/tokenSubmitSuccess.html b/src/main/resources/templates/session/tokenSubmitSuccess.html
similarity index 100%
rename from src/main/resources/templates/session/local/tokenSubmitSuccess.html
rename to src/main/resources/templates/session/tokenSubmitSuccess.html
diff --git a/src/main/resources/threepids/email/invite-template.eml b/src/main/resources/threepids/email/invite-template.eml
index c422476..1df3df3 100644
--- a/src/main/resources/threepids/email/invite-template.eml
+++ b/src/main/resources/threepids/email/invite-template.eml
@@ -10,10 +10,9 @@ Content-Disposition: inline
Hi,
%SENDER_NAME_OR_ID% has invited you into a room [%ROOM_NAME_OR_ID%] on
-Matrix. To join the conversation, register an account on http://%DOMAIN%
+Matrix. To join the conversation, register an account on https://%DOMAIN%
-You can also register an account on a public server, like Matrix.org, by going to
-https://riot.im/app/#/register?%INVITE_MEDIUM%=%INVITE_ADDRESS%
+You can also register an account on a public server and get in touch with them.
About Matrix:
@@ -70,10 +69,9 @@ pre, code {
Hi,
%SENDER_NAME_OR_ID% has invited you into a room [%ROOM_NAME_OR_ID%] on
-Matrix. To join the conversation, register an account on %DOMAIN%.
+Matrix. To join the conversation, register an account on %DOMAIN%.
-You can also register an account on a public server, like Matrix.org, by following
-this link.
+
About Matrix:
diff --git a/src/main/resources/threepids/email/validate-remote-template.eml b/src/main/resources/threepids/email/validate-remote-template.eml
deleted file mode 100644
index 5bcca92..0000000
--- a/src/main/resources/threepids/email/validate-remote-template.eml
+++ /dev/null
@@ -1,102 +0,0 @@
-Subject: Linking your Email address to your Matrix account
-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.
-
-Due to the security policy in place, this email address can only be stored in the central Matrix Identity Server.
-If you continue, your e-mail address and Matrix ID association will be made public without any current mean to be removed.
-
-If you would still like to continue, you will need to:
-1. Go to your private Public registration process page:
-
- %VALIDATION_LINK%
-
-2. Follow the registration process of the central Identity Server, usually another email with similar content
-3. Once your email address validated with the central Identity Server, click on "Continue" on page of step #1
-4. If your public association is found by our Identity server, the next step will be given to you.
-
-
-If you didn't make this request, or do not want to make your address public, you can safely disregard this email.
-
-%DOMAIN_PRETTY% Admins
-
---7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
-Content-Type: multipart/related;
- boundary="M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR";
- type="text/html"
-
---M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR
-Content-Type: text/html; charset=UTF-8
-Content-Disposition: inline
-
-
-
-
-
-
-
-
-
- |
-
- Hello there!
-
- We have received a request to link this email address with your Matrix account.
-
- Due to the security policy in place, this email address can only be stored in the central Matrix Identity Server.
- If you continue, your e-mail address and Matrix ID association will be made public without any current mean to be removed.
-
- If you would still like to continue, you will need to:
-
- - Go to your private Public registration process page
- - Follow the registration process of the central Identity Server, usually another email with similar content
- - Once your email address validated with the central Identity Server, click on "Continue" on page of step #1
- - If your public association is found by our Identity server, the next step will be given to you.
-
-
-
- If you didn't make this request, or do not want to make your address public, you can safely disregard this email.
-
- %DOMAIN_PRETTY% Admins
- |
- |
-
-
-
-
---M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR--
-
---7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ--
diff --git a/src/main/resources/threepids/email/validate-local-template.eml b/src/main/resources/threepids/email/validate-template.eml
similarity index 91%
rename from src/main/resources/threepids/email/validate-local-template.eml
rename to src/main/resources/threepids/email/validate-template.eml
index 78df56e..5c4ca3f 100644
--- a/src/main/resources/threepids/email/validate-local-template.eml
+++ b/src/main/resources/threepids/email/validate-template.eml
@@ -9,7 +9,7 @@ Content-Disposition: inline
Hello there!
-We have received a request to link this email address with your Matrix account.
+You or a server on your behalf requested to validate your email.
If it was really you who made this request, you can click on the following link to
complete the verification of your email address:
@@ -66,7 +66,7 @@ pre, code {
Hello there!
- We have received a request to link this email address with your Matrix account.
+ You or a server on your behalf requested to validate your email.
If it was really you who made this request, you can click on the following link to
complete the verification of your email address:
diff --git a/src/main/resources/threepids/sms/invite-template.txt b/src/main/resources/threepids/sms/invite-template.txt
index ff6125a..66f975c 100644
--- a/src/main/resources/threepids/sms/invite-template.txt
+++ b/src/main/resources/threepids/sms/invite-template.txt
@@ -1 +1 @@
-You have been invited to a Matrix room by %SENDER_NAME_OR_ID%. Visit https://riot.im/ or any public server to join and start chatting!
\ No newline at end of file
+You have been invited to a Matrix room by %SENDER_NAME_OR_ID%. Please get in touch with them for further instructions.
\ No newline at end of file
diff --git a/src/main/resources/threepids/sms/validate-remote-template.txt b/src/main/resources/threepids/sms/validate-remote-template.txt
deleted file mode 100644
index e36ea5b..0000000
--- a/src/main/resources/threepids/sms/validate-remote-template.txt
+++ /dev/null
@@ -1 +0,0 @@
-Your phone number will be made publicly searchable. To continue, you will need to enter two codes. Your first code is %VALIDATION_TOKEN%
\ No newline at end of file
diff --git a/src/main/resources/threepids/sms/validate-local-template.txt b/src/main/resources/threepids/sms/validate-template.txt
similarity index 100%
rename from src/main/resources/threepids/sms/validate-local-template.txt
rename to src/main/resources/threepids/sms/validate-template.txt
|