Continue structural port from Spring Boot to Undertow

This commit is contained in:
Max Dor
2018-12-30 05:28:05 +01:00
parent 6a376db322
commit 7ad985fead
85 changed files with 1019 additions and 367 deletions

View File

@@ -0,0 +1,114 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.http.undertow.handler.SaneHandler;
import io.kamax.mxisd.http.undertow.handler.as.v1.AsNotFoundHandler;
import io.kamax.mxisd.http.undertow.handler.as.v1.AsTransactionHandler;
import io.kamax.mxisd.http.undertow.handler.auth.RestAuthHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginGetHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginPostHandler;
import io.kamax.mxisd.http.undertow.handler.directory.v1.UserDirectorySearchHandler;
import io.kamax.mxisd.http.undertow.handler.identity.v1.*;
import io.kamax.mxisd.http.undertow.handler.profile.v1.InternalProfileHandler;
import io.kamax.mxisd.http.undertow.handler.profile.v1.ProfileHandler;
import io.kamax.mxisd.http.undertow.handler.status.StatusHandler;
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
public class HttpMxisd {
// Core
private Mxisd m;
// I/O
private Undertow httpSrv;
public HttpMxisd(MxisdConfig cfg) {
m = new Mxisd(cfg);
}
public void start() {
m.start();
HttpHandler asNotFoundHandler = SaneHandler.around(new AsNotFoundHandler(m.getAs()));
HttpHandler asTxnHandler = SaneHandler.around(new AsTransactionHandler(m.getAs()));
HttpHandler storeInvHandler = SaneHandler.around(new StoreInviteHandler(m.getConfig().getServer(), m.getInvitationManager(), m.getKeyManager()));
HttpHandler sessValidateHandler = SaneHandler.around(new SessionValidateHandler(m.getSession(), m.getConfig().getServer(), m.getConfig().getView()));
httpSrv = Undertow.builder().addHttpListener(m.getConfig().getServer().getPort(), "0.0.0.0").setHandler(Handlers.routing()
// Status endpoints
.get(StatusHandler.Path, SaneHandler.around(new StatusHandler()))
// Authentication endpoints
.get(LoginHandler.Path, SaneHandler.around(new LoginGetHandler(m.getAuth(), m.getHttpClient())))
.post(LoginHandler.Path, SaneHandler.around(new LoginPostHandler(m.getAuth())))
.post(RestAuthHandler.Path, SaneHandler.around(new RestAuthHandler(m.getAuth())))
// Directory endpoints
.post(UserDirectorySearchHandler.Path, SaneHandler.around(new UserDirectorySearchHandler(m.getDirectory())))
// Key endpoints
.get(KeyGetHandler.Path, SaneHandler.around(new KeyGetHandler(m.getKeyManager())))
.get(RegularKeyIsValidHandler.Path, SaneHandler.around(new RegularKeyIsValidHandler(m.getKeyManager())))
.get(EphemeralKeyIsValidHandler.Path, SaneHandler.around(new EphemeralKeyIsValidHandler()))
// Identity endpoints
.get(HelloHandler.Path, new HelloHandler())
.get(SingleLookupHandler.Path, new SingleLookupHandler(m.getIdentity(), m.getSign()))
.post(BulkLookupHandler.Path, new BulkLookupHandler(m.getIdentity()))
.post(StoreInviteHandler.Path, storeInvHandler)
.post(SessionStartHandler.Path, SaneHandler.around(new SessionStartHandler(m.getSession())))
.get(SessionValidateHandler.Path, sessValidateHandler)
.post(SessionValidateHandler.Path, sessValidateHandler)
.get(SessionTpidGetValidatedHandler.Path, SaneHandler.around(new SessionTpidGetValidatedHandler(m.getSession())))
.post(SessionTpidBindHandler.Path, SaneHandler.around(new SessionTpidBindHandler(m.getSession(), m.getInvitationManager())))
.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())))
.get(InternalProfileHandler.Path, SaneHandler.around(new InternalProfileHandler(m.getProfile())))
// Application Service endpoints
.get("/_matrix/app/v1/users/**", asNotFoundHandler)
.get("/users/**", asNotFoundHandler) // Legacy endpoint
.get("/_matrix/app/v1/rooms/**", asNotFoundHandler)
.get("/rooms/**", asNotFoundHandler) // Legacy endpoint
.put(AsTransactionHandler.Path, asTxnHandler)
.put("/transactions/{" + AsTransactionHandler.ID + "}", asTxnHandler) // Legacy endpoint
).build();
httpSrv.start();
}
public void stop() {
httpSrv.stop();
m.stop();
}
}

View File

@@ -28,38 +28,26 @@ import io.kamax.mxisd.auth.AuthProviders;
import io.kamax.mxisd.backend.IdentityStoreSupplier;
import io.kamax.mxisd.backend.sql.synapse.Synapse;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.crypto.CryptoFactory;
import io.kamax.mxisd.directory.DirectoryManager;
import io.kamax.mxisd.directory.DirectoryProviders;
import io.kamax.mxisd.dns.ClientDnsOverwrite;
import io.kamax.mxisd.dns.FederationDnsOverwrite;
import io.kamax.mxisd.http.undertow.handler.SaneHandler;
import io.kamax.mxisd.http.undertow.handler.as.v1.AsNotFoundHandler;
import io.kamax.mxisd.http.undertow.handler.as.v1.AsTransactionHandler;
import io.kamax.mxisd.http.undertow.handler.auth.RestAuthHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginGetHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginHandler;
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginPostHandler;
import io.kamax.mxisd.http.undertow.handler.directory.v1.UserDirectorySearchHandler;
import io.kamax.mxisd.http.undertow.handler.identity.v1.*;
import io.kamax.mxisd.http.undertow.handler.profile.v1.InternalProfileHandler;
import io.kamax.mxisd.http.undertow.handler.profile.v1.ProfileHandler;
import io.kamax.mxisd.http.undertow.handler.status.StatusHandler;
import io.kamax.mxisd.invitation.InvitationManager;
import io.kamax.mxisd.lookup.ThreePidProviders;
import io.kamax.mxisd.lookup.fetcher.IRemoteIdentityServerFetcher;
import io.kamax.mxisd.lookup.provider.BridgeFetcher;
import io.kamax.mxisd.lookup.provider.RemoteIdentityServerFetcher;
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
import io.kamax.mxisd.lookup.strategy.RecursivePriorityLookupStrategy;
import io.kamax.mxisd.notification.NotificationHandlerSupplier;
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.spring.CryptoFactory;
import io.kamax.mxisd.storage.IStorage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqliteStorage;
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
@@ -67,55 +55,58 @@ import java.util.ServiceLoader;
public class Mxisd {
private MxisdConfig cfg;
protected MxisdConfig cfg;
private CloseableHttpClient httpClient;
protected CloseableHttpClient httpClient;
protected IRemoteIdentityServerFetcher srvFetcher;
private KeyManager keyMgr;
private SignatureManager signMgr;
protected IStorage store;
protected KeyManager keyMgr;
protected SignatureManager signMgr;
// Features
private AuthManager authMgr;
private DirectoryManager dirMgr;
private LookupStrategy idStrategy;
private InvitationManager invMgr;
private ProfileManager pMgr;
private AppSvcManager asHander;
private SessionMananger sessMgr;
// I/O
private Undertow httpSrv;
protected AuthManager authMgr;
protected DirectoryManager dirMgr;
protected LookupStrategy idStrategy;
protected InvitationManager invMgr;
protected ProfileManager pMgr;
protected AppSvcManager asHander;
protected SessionMananger sessMgr;
protected NotificationManager notifMgr;
public Mxisd(MxisdConfig cfg) {
this.cfg = cfg.build();
}
private void build() {
protected void build() {
httpClient = HttpClients.custom()
.setUserAgent("mxisd")
.setMaxConnPerRoute(Integer.MAX_VALUE)
.setMaxConnTotal(Integer.MAX_VALUE)
.build();
OrmLiteSqliteStorage storage = new OrmLiteSqliteStorage(cfg);
srvFetcher = new RemoteIdentityServerFetcher(httpClient);
store = new OrmLiteSqliteStorage(cfg);
keyMgr = CryptoFactory.getKeyManager(cfg.getKey());
signMgr = CryptoFactory.getSignatureManager(keyMgr, cfg.getServer());
ClientDnsOverwrite clientDns = new ClientDnsOverwrite(cfg.getDns().getOverwrite());
FederationDnsOverwrite fedDns = new FederationDnsOverwrite(cfg.getDns().getOverwrite());
pMgr = new ProfileManager(ProfileProviders.get(), clientDns, httpClient);
NotificationManager notifMgr = new NotificationManager(cfg.getNotification(), NotificationHandlers.get());
Synapse synapse = new Synapse(cfg.getSynapseSql());
RemoteIdentityServerFetcher srvFetcher = new RemoteIdentityServerFetcher(httpClient);
BridgeFetcher bridgeFetcher = new BridgeFetcher(cfg.getLookup().getRecursive().getBridge(), srvFetcher);
idStrategy = new RecursivePriorityLookupStrategy(cfg.getLookup(), ThreePidProviders.get(), bridgeFetcher);
invMgr = new InvitationManager(cfg.getInvite(), storage, idStrategy, signMgr, fedDns, notifMgr);
sessMgr = new SessionMananger(cfg.getSession(), cfg.getMatrix(), storage, notifMgr, httpClient);
authMgr = new AuthManager(cfg, AuthProviders.get(), idStrategy, invMgr, clientDns, httpClient);
dirMgr = new DirectoryManager(cfg.getDirectory(), clientDns, httpClient, DirectoryProviders.get());
asHander = new AppSvcManager(cfg, storage, pMgr, notifMgr, synapse);
ServiceLoader.load(IdentityStoreSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
ServiceLoader.load(NotificationHandlerSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
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, 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());
asHander = new AppSvcManager(cfg, store, pMgr, notifMgr, synapse);
}
public MxisdConfig getConfig() {
@@ -126,68 +117,56 @@ public class Mxisd {
return httpClient;
}
public IRemoteIdentityServerFetcher getServerFetcher() {
return srvFetcher;
}
public KeyManager getKeyManager() {
return keyMgr;
}
public InvitationManager getInvitationManager() {
return invMgr;
}
public LookupStrategy getIdentity() {
return idStrategy;
}
public AuthManager getAuth() {
return authMgr;
}
public SessionMananger getSession() {
return sessMgr;
}
public DirectoryManager getDirectory() {
return dirMgr;
}
public ProfileManager getProfile() {
return pMgr;
}
public SignatureManager getSign() {
return signMgr;
}
public AppSvcManager getAs() {
return asHander;
}
public NotificationManager getNotif() {
return notifMgr;
}
public void start() {
build();
HttpHandler asNotFoundHandler = SaneHandler.around(new AsNotFoundHandler(asHander));
HttpHandler asTxnHandler = SaneHandler.around(new AsTransactionHandler(asHander));
HttpHandler storeInvHandler = SaneHandler.around(new StoreInviteHandler(cfg.getServer(), invMgr, keyMgr));
HttpHandler sessValidateHandler = SaneHandler.around(new SessionValidateHandler(sessMgr, cfg.getServer(), cfg.getView()));
httpSrv = Undertow.builder().addHttpListener(cfg.getServer().getPort(), "0.0.0.0").setHandler(Handlers.routing()
// Status endpoints
.get(StatusHandler.Path, SaneHandler.around(new StatusHandler()))
// Authentication endpoints
.get(LoginHandler.Path, SaneHandler.around(new LoginGetHandler(authMgr, httpClient)))
.post(LoginHandler.Path, SaneHandler.around(new LoginPostHandler(authMgr)))
.post(RestAuthHandler.Path, SaneHandler.around(new RestAuthHandler(authMgr)))
// Directory endpoints
.post(UserDirectorySearchHandler.Path, SaneHandler.around(new UserDirectorySearchHandler(dirMgr)))
// Key endpoints
.get(KeyGetHandler.Path, SaneHandler.around(new KeyGetHandler(keyMgr)))
.get(RegularKeyIsValidHandler.Path, SaneHandler.around(new RegularKeyIsValidHandler(keyMgr)))
.get(EphemeralKeyIsValidHandler.Path, SaneHandler.around(new EphemeralKeyIsValidHandler()))
// Identity endpoints
.get(HelloHandler.Path, new HelloHandler())
.get(SingleLookupHandler.Path, new SingleLookupHandler(idStrategy, signMgr))
.post(BulkLookupHandler.Path, new BulkLookupHandler(idStrategy))
.post(StoreInviteHandler.Path, storeInvHandler)
.post(SessionStartHandler.Path, SaneHandler.around(new SessionStartHandler(sessMgr)))
.get(SessionValidateHandler.Path, sessValidateHandler)
.post(SessionValidateHandler.Path, sessValidateHandler)
.get(SessionTpidGetValidatedHandler.Path, SaneHandler.around(new SessionTpidGetValidatedHandler(sessMgr)))
.post(SessionTpidBindHandler.Path, SaneHandler.around(new SessionTpidBindHandler(sessMgr, invMgr)))
.get(RemoteIdentityAPIv1.SESSION_REQUEST_TOKEN, SaneHandler.around(new RemoteSessionStartHandler(sessMgr, cfg.getView())))
.get(RemoteIdentityAPIv1.SESSION_CHECK, SaneHandler.around(new RemoteSessionCheckHandler(sessMgr, cfg.getView())))
// Profile endpoints
.get(ProfileHandler.Path, SaneHandler.around(new ProfileHandler(pMgr)))
.get(InternalProfileHandler.Path, SaneHandler.around(new InternalProfileHandler(pMgr)))
// Application Service endpoints
.get("/_matrix/app/v1/users/**", asNotFoundHandler)
.get("/users/**", asNotFoundHandler) // Legacy endpoint
.get("/_matrix/app/v1/rooms/**", asNotFoundHandler)
.get("/rooms/**", asNotFoundHandler) // Legacy endpoint
.put(AsTransactionHandler.Path, asTxnHandler)
.put("/transactions/{" + AsTransactionHandler.ID + "}", asTxnHandler) // Legacy endpoint
).build();
httpSrv.start();
}
public void stop() {
httpSrv.stop();
// no-op
}
}

View File

@@ -28,8 +28,13 @@ import java.io.IOException;
public class MxisdStandaloneExec {
public static void main(String[] args) throws IOException {
MxisdConfig cfg = YamlConfigLoader.loadFromFile("mxisd.yaml"); // FIXME no hardcoding, make it configurable via Build, Env and CLI parameters
new Mxisd(cfg).start();
// FIXME no hard-coding, make it configurable via Build, Env and CLI parameters
MxisdConfig cfg = YamlConfigLoader.loadFromFile("mxisd.yaml");
HttpMxisd mxisd = new HttpMxisd(cfg);
Runtime.getRuntime().addShutdownHook(new Thread(mxisd::stop));
mxisd.start();
}
}

View File

@@ -25,12 +25,12 @@ import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.config.ExecConfig;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.http.io.UserDirectorySearchRequest;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import org.apache.commons.lang3.StringUtils;
public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider {
public class ExecDirectoryStore extends ExecStore implements DirectoryProvider {
private ExecConfig.Directory cfg;
private MatrixConfig mxCfg;
@@ -44,11 +44,6 @@ public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
private UserDirectorySearchResult search(ExecConfig.Process cfg, UserDirectorySearchRequest request) {
if (StringUtils.isEmpty(cfg.getCommand())) {
return UserDirectorySearchResult.empty();

View File

@@ -63,11 +63,6 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
@Override
public boolean isLocal() {
return true;

View File

@@ -45,11 +45,6 @@ public class ExecProfileStore extends ExecStore implements ProfileProvider {
this.cfg = cfg;
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
private Optional<JsonProfileResult> getFull(_MatrixID userId, ExecConfig.Process cfg) {
Processor<Optional<JsonProfileResult>> p = new Processor<>(cfg);

View File

@@ -22,7 +22,7 @@ package io.kamax.mxisd.backend.ldap;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ldap.LdapConfig;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import io.kamax.mxisd.util.GsonUtil;
@@ -40,7 +40,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class LdapDirectoryProvider extends LdapBackend implements IDirectoryProvider {
public class LdapDirectoryProvider extends LdapBackend implements DirectoryProvider {
private transient final Logger log = LoggerFactory.getLogger(LdapDirectoryProvider.class);
@@ -48,11 +48,6 @@ public class LdapDirectoryProvider extends LdapBackend implements IDirectoryProv
super(cfg, mxCfg);
}
@Override
public boolean isEnabled() {
return getCfg().isEnabled();
}
protected UserDirectorySearchResult search(String query, List<String> attributes) {
UserDirectorySearchResult result = new UserDirectorySearchResult();
result.setLimited(false);

View File

@@ -51,11 +51,6 @@ public class LdapProfileProvider extends LdapBackend implements ProfileProvider
super(cfg, mxCfg);
}
@Override
public boolean isEnabled() {
return getCfg().isEnabled();
}
@Override
public Optional<String> getDisplayName(_MatrixID userId) {
String uid = buildUidFromMatrixId(userId);

View File

@@ -51,11 +51,6 @@ public class LdapThreePidProvider extends LdapBackend implements IThreePidProvid
super(cfg, mxCfg);
}
@Override
public boolean isEnabled() {
return getCfg().isEnabled();
}
@Override
public boolean isLocal() {
return true;

View File

@@ -31,7 +31,7 @@ import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.memory.MemoryIdentityConfig;
import io.kamax.mxisd.config.memory.MemoryStoreConfig;
import io.kamax.mxisd.config.memory.MemoryThreePid;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest;
@@ -49,7 +49,7 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
public class MemoryIdentityStore implements AuthenticatorProvider, IDirectoryProvider, IThreePidProvider, ProfileProvider {
public class MemoryIdentityStore implements AuthenticatorProvider, DirectoryProvider, IThreePidProvider, ProfileProvider {
private transient final Logger logger = LoggerFactory.getLogger(MemoryIdentityStore.class);

View File

@@ -23,19 +23,18 @@ package io.kamax.mxisd.backend.rest;
import io.kamax.matrix.MatrixID;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.rest.RestBackendConfig;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.http.io.UserDirectorySearchRequest;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import io.kamax.mxisd.util.RestClientUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class RestDirectoryProvider extends RestProvider implements IDirectoryProvider {
public class RestDirectoryProvider extends RestProvider implements DirectoryProvider {
private MatrixConfig mxCfg;
@@ -44,11 +43,6 @@ public class RestDirectoryProvider extends RestProvider implements IDirectoryPro
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return cfg.isEnabled() && StringUtils.isNotBlank(cfg.getEndpoints().getDirectory());
}
private UserDirectorySearchResult search(String by, String query) {
UserDirectorySearchRequest request = new UserDirectorySearchRequest(query);
request.setBy(by);

View File

@@ -55,11 +55,6 @@ public class RestProfileProvider extends RestProvider implements ProfileProvider
super(cfg);
}
@Override
public boolean isEnabled() {
return cfg.isEnabled() && cfg.getEndpoints().getProfile().isPresent();
}
private <T> Optional<T> doRequest(
_MatrixID userId,
Function<RestBackendConfig.ProfileEndpoints, Optional<String>> endpoint,

View File

@@ -62,11 +62,6 @@ public class RestThreePidProvider extends RestProvider implements IThreePidProvi
}
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
@Override
public boolean isLocal() {
return true;

View File

@@ -50,11 +50,6 @@ public abstract class SqlProfileProvider implements ProfileProvider {
this.pool = new SqlConnectionPool(cfg);
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
@Override
public Optional<String> getDisplayName(_MatrixID user) {
String stmtSql = cfg.getDisplayName().getQuery();

View File

@@ -54,11 +54,6 @@ public abstract class SqlThreePidProvider implements IThreePidProvider {
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return cfg.isEnabled();
}
@Override
public boolean isLocal() {
return true;

View File

@@ -25,7 +25,7 @@ import io.kamax.mxisd.backend.sql.SqlConnectionPool;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.SqlConfig;
import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import org.apache.commons.lang.StringUtils;
@@ -40,7 +40,7 @@ import java.util.Optional;
import static io.kamax.mxisd.http.io.UserDirectorySearchResult.Result;
public class GenericSqlDirectoryProvider implements IDirectoryProvider {
public class GenericSqlDirectoryProvider implements DirectoryProvider {
private transient final Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class);
@@ -55,11 +55,6 @@ public class GenericSqlDirectoryProvider implements IDirectoryProvider {
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return cfg.getDirectory().isEnabled();
}
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
for (int i = 1; i <= stmt.getParameterMetaData().getParameterCount(); i++) {
stmt.setString(i, searchTerm);

View File

@@ -23,7 +23,7 @@ package io.kamax.mxisd.backend.wordpress;
import io.kamax.matrix.MatrixID;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.wordpress.WordpressConfig;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.directory.DirectoryProvider;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
import org.slf4j.Logger;
@@ -35,7 +35,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
public class WordpressDirectoryProvider implements IDirectoryProvider {
public class WordpressDirectoryProvider implements DirectoryProvider {
private transient final Logger log = LoggerFactory.getLogger(WordpressDirectoryProvider.class);
@@ -49,11 +49,6 @@ public class WordpressDirectoryProvider implements IDirectoryProvider {
this.mxCfg = mxCfg;
}
@Override
public boolean isEnabled() {
return wordpress.isEnabled();
}
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
for (int i = 1; i <= stmt.getParameterMetaData().getParameterCount(); i++) {
stmt.setString(i, "%" + searchTerm + "%");

View File

@@ -54,11 +54,6 @@ public class WordpressThreePidProvider implements IThreePidProvider {
this.wordpress = wordpress;
}
@Override
public boolean isEnabled() {
return wordpress.isEnabled();
}
@Override
public boolean isLocal() {
return true;

View File

@@ -53,7 +53,7 @@ public class InvitationConfig {
}
private Resolution resolution;
private Resolution resolution = new Resolution();
public Resolution getResolution() {
return resolution;

View File

@@ -21,7 +21,10 @@
package io.kamax.mxisd.config.threepid;
import com.google.gson.JsonObject;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import java.util.HashMap;
import java.util.Map;
@@ -31,7 +34,8 @@ public class ThreePidConfig {
private Map<String, JsonObject> medium = new HashMap<>();
public ThreePidConfig() {
EmailConfig emailCfg = new EmailConfig();
medium.put(ThreePidMedium.Email.getId(), GsonUtil.makeObj(new EmailConfig()));
medium.put(ThreePidMedium.PhoneNumber.getId(), GsonUtil.makeObj(new PhoneConfig()));
}
public Map<String, JsonObject> getMedium() {

View File

@@ -24,13 +24,11 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
public class EmailSmtpConfig {
private transient final Logger log = LoggerFactory.getLogger(EmailSmtpConfig.class);
private String host;
private String host = "";
private int port = 587;
private int tls = 1;
private String login;
@@ -76,14 +74,15 @@ public class EmailSmtpConfig {
this.password = password;
}
@PostConstruct
public void build() {
public EmailSmtpConfig build() {
log.info("--- E-mail SMTP Connector config ---");
log.info("Host: {}", getHost());
log.info("Port: {}", getPort());
log.info("TLS Mode: {}", getTls());
log.info("Login: {}", getLogin());
log.info("Has password: {}", StringUtils.isNotBlank(getPassword()));
return this;
}
}

View File

@@ -23,16 +23,12 @@ package io.kamax.mxisd.config.threepid.connector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
public class PhoneTwilioConfig {
static final String NAMESPACE = "threepid.medium.msisdn.connectors.twilio";
private transient final Logger log = LoggerFactory.getLogger(PhoneTwilioConfig.class);
private String accountSid;
private String authToken;
private String accountSid = "";
private String authToken = "";
private String number;
public String getAccountSid() {
@@ -59,11 +55,12 @@ public class PhoneTwilioConfig {
this.number = number;
}
@PostConstruct
public void build() {
public PhoneTwilioConfig build() {
log.info("--- Phone SMS Twilio connector config ---");
log.info("Account SID: {}", getAccountSid());
log.info("Sender number: {}", getNumber());
return this;
}
}

View File

@@ -20,12 +20,8 @@
package io.kamax.mxisd.config.threepid.medium;
import io.kamax.mxisd.exception.ConfigurationException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import io.kamax.mxisd.threepid.connector.email.EmailSmtpConnector;
import io.kamax.mxisd.threepid.generator.email.GenericEmailNotificationGenerator;
public class EmailConfig extends MediumConfig {
@@ -52,35 +48,15 @@ public class EmailConfig extends MediumConfig {
}
private transient final Logger log = LoggerFactory.getLogger(EmailConfig.class);
private Identity identity = new Identity();
public EmailConfig() {
setConnector("smtp");
setGenerator("template");
setConnector(EmailSmtpConnector.ID);
setGenerator(GenericEmailNotificationGenerator.ID);
}
public Identity getIdentity() {
return identity;
}
@PostConstruct
public void build() {
log.info("--- E-mail config ---");
if (StringUtils.isBlank(getGenerator())) {
throw new ConfigurationException("generator");
}
if (StringUtils.isBlank(getConnector())) {
throw new ConfigurationException("connector");
}
log.info("From: {}", getIdentity().getFrom());
log.info("Name: {}", getIdentity().getName());
log.info("Generator: {}", getGenerator());
log.info("Connector: {}", getConnector());
}
}

View File

@@ -23,8 +23,6 @@ package io.kamax.mxisd.config.threepid.medium;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
public class EmailTemplateConfig extends GenericTemplateConfig {
private transient final Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class);
@@ -36,13 +34,14 @@ public class EmailTemplateConfig extends GenericTemplateConfig {
getSession().getValidation().setRemote("classpath:threepids/email/validate-remote-template.eml");
}
@PostConstruct
public void build() {
public EmailTemplateConfig build() {
log.info("--- E-mail Generator templates config ---");
log.info("Invite: {}", getName(getInvite()));
log.info("Session validation:");
log.info("\tLocal: {}", getName(getSession().getValidation().getLocal()));
log.info("\tRemote: {}", getName(getSession().getValidation().getRemote()));
return this;
}
}

View File

@@ -62,7 +62,7 @@ public class GenericTemplateConfig {
}
private SessionValidation validation;
private SessionValidation validation = new SessionValidation();
public SessionValidation getValidation() {
return validation;

View File

@@ -20,16 +20,14 @@
package io.kamax.mxisd.config.threepid.medium;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.kamax.mxisd.threepid.connector.phone.PhoneSmsTwilioConnector;
import io.kamax.mxisd.threepid.generator.phone.SmsNotificationGenerator;
public class PhoneConfig extends MediumConfig {
private transient final Logger log = LoggerFactory.getLogger(PhoneConfig.class);
public PhoneConfig() {
setConnector("twilio");
setGenerator("template");
setConnector(PhoneSmsTwilioConnector.ID);
setGenerator(SmsNotificationGenerator.ID);
}
}

View File

@@ -23,8 +23,6 @@ package io.kamax.mxisd.config.threepid.medium;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
public class PhoneSmsTemplateConfig extends GenericTemplateConfig {
private transient final Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class);
@@ -36,13 +34,14 @@ public class PhoneSmsTemplateConfig extends GenericTemplateConfig {
getSession().getValidation().setRemote("classpath:threepids/sms/validate-remote-template.txt");
}
@PostConstruct
public void build() {
public PhoneSmsTemplateConfig build() {
log.info("--- SMS Generator templates config ---");
log.info("Invite: {}", getName(getInvite()));
log.info("Session validation:");
log.info("\tLocal: {}", getName(getSession().getValidation().getLocal()));
log.info("\tRemote: {}", getName(getSession().getValidation().getRemote()));
return this;
}
}

View File

@@ -21,6 +21,9 @@
package io.kamax.mxisd.config.threepid.notification;
import com.google.gson.JsonObject;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.threepid.notification.email.EmailRawNotificationHandler;
import io.kamax.mxisd.threepid.notification.phone.PhoneNotificationHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,6 +38,11 @@ public class NotificationConfig {
private Map<String, String> handler = new HashMap<>();
private Map<String, JsonObject> handlers = new HashMap<>();
public NotificationConfig() {
handler.put(ThreePidMedium.Email.getId(), EmailRawNotificationHandler.ID);
handler.put(ThreePidMedium.PhoneNumber.getId(), PhoneNotificationHandler.ID);
}
public Map<String, String> getHandler() {
return handler;
}

View File

@@ -18,14 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.spring;
package io.kamax.mxisd.crypto;
import io.kamax.matrix.crypto.KeyFileStore;
import io.kamax.matrix.crypto.KeyManager;
import io.kamax.matrix.crypto.SignatureManager;
import io.kamax.matrix.crypto.*;
import io.kamax.mxisd.config.KeyConfig;
import io.kamax.mxisd.config.ServerConfig;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
@@ -33,16 +32,23 @@ import java.io.IOException;
public class CryptoFactory {
public static KeyManager getKeyManager(KeyConfig keyCfg) {
File keyStore = new File(keyCfg.getPath());
if (!keyStore.exists()) {
try {
FileUtils.touch(keyStore);
} catch (IOException e) {
throw new RuntimeException(e);
_KeyStore store;
if (StringUtils.equals(":memory:", keyCfg.getPath())) {
store = new KeyMemoryStore();
} else {
File keyStore = new File(keyCfg.getPath());
if (!keyStore.exists()) {
try {
FileUtils.touch(keyStore);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
store = new KeyFileStore(keyCfg.getPath());
}
return new KeyManager(new KeyFileStore(keyCfg.getPath()));
return new KeyManager(store);
}
public static SignatureManager getSignatureManager(KeyManager keyMgr, ServerConfig cfg) {

View File

@@ -43,8 +43,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class DirectoryManager {
@@ -53,13 +53,13 @@ public class DirectoryManager {
private DirectoryConfig cfg;
private ClientDnsOverwrite dns;
private CloseableHttpClient client;
private List<IDirectoryProvider> providers;
private List<DirectoryProvider> providers;
public DirectoryManager(DirectoryConfig cfg, ClientDnsOverwrite dns, CloseableHttpClient client, List<? extends IDirectoryProvider> providers) {
public DirectoryManager(DirectoryConfig cfg, ClientDnsOverwrite dns, CloseableHttpClient client, List<? extends DirectoryProvider> providers) {
this.cfg = cfg;
this.dns = dns;
this.client = client;
this.providers = providers.stream().filter(IDirectoryProvider::isEnabled).collect(Collectors.toList());
this.providers = new ArrayList<>(providers);
log.info("Directory providers:");
this.providers.forEach(p -> log.info("\t- {}", p.getClass().getName()));
@@ -111,7 +111,7 @@ public class DirectoryManager {
}
}
for (IDirectoryProvider provider : providers) {
for (DirectoryProvider provider : providers) {
log.info("Using Directory provider {}", provider.getClass().getSimpleName());
UserDirectorySearchResult resultProvider = provider.searchByDisplayName(query);
log.info("Display name: found {} match(es) for '{}'", resultProvider.getResults().size(), query);

View File

@@ -22,9 +22,7 @@ package io.kamax.mxisd.directory;
import io.kamax.mxisd.http.io.UserDirectorySearchResult;
public interface IDirectoryProvider {
boolean isEnabled();
public interface DirectoryProvider {
UserDirectorySearchResult searchByDisplayName(String query);

View File

@@ -27,13 +27,13 @@ import java.util.stream.Collectors;
public class DirectoryProviders {
private static final List<Supplier<? extends IDirectoryProvider>> suppliers = new ArrayList<>();
private static final List<Supplier<? extends DirectoryProvider>> suppliers = new ArrayList<>();
public static void register(Supplier<? extends IDirectoryProvider> supplier) {
public static void register(Supplier<? extends DirectoryProvider> supplier) {
suppliers.add(supplier);
}
public static List<? extends IDirectoryProvider> get() {
public static List<? extends DirectoryProvider> get() {
return suppliers.stream().map(Supplier::get).collect(Collectors.toList());
}

View File

@@ -25,6 +25,7 @@ import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest;
import io.kamax.mxisd.lookup.ThreePidMapping;
import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher;
import io.kamax.mxisd.lookup.fetcher.IRemoteIdentityServerFetcher;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,9 +39,9 @@ public class BridgeFetcher implements IBridgeFetcher {
private transient final Logger log = LoggerFactory.getLogger(BridgeFetcher.class);
private RecursiveLookupBridgeConfig cfg;
private RemoteIdentityServerFetcher fetcher;
private IRemoteIdentityServerFetcher fetcher;
public BridgeFetcher(RecursiveLookupBridgeConfig cfg, RemoteIdentityServerFetcher fetcher) {
public BridgeFetcher(RecursiveLookupBridgeConfig cfg, IRemoteIdentityServerFetcher fetcher) {
this.cfg = cfg;
this.fetcher = fetcher;
}

View File

@@ -47,11 +47,6 @@ class DnsLookupProvider implements IThreePidProvider {
this.fetcher = fetcher;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isLocal() {
return false;

View File

@@ -22,6 +22,7 @@ package io.kamax.mxisd.lookup.provider;
import io.kamax.mxisd.config.ForwardConfig;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest;
import io.kamax.mxisd.lookup.ThreePidMapping;
@@ -41,17 +42,16 @@ public class ForwarderProvider implements IThreePidProvider {
private MatrixConfig mxCfg;
private IRemoteIdentityServerFetcher fetcher;
public ForwarderProvider(MxisdConfig cfg, IRemoteIdentityServerFetcher fetcher) {
this(cfg.getForward(), cfg.getMatrix(), fetcher);
}
public ForwarderProvider(ForwardConfig cfg, MatrixConfig mxCfg, IRemoteIdentityServerFetcher fetcher) {
this.cfg = cfg;
this.mxCfg = mxCfg;
this.fetcher = fetcher;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isLocal() {
return false;

View File

@@ -29,8 +29,6 @@ import java.util.Optional;
public interface IThreePidProvider {
boolean isEnabled();
boolean isLocal();
/**

View File

@@ -0,0 +1,35 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.lookup.provider;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.backend.IdentityStoreSupplier;
import io.kamax.mxisd.lookup.ThreePidProviders;
public class RemoteLookupProviderSupplier implements IdentityStoreSupplier {
@Override
public void accept(Mxisd mxisd) {
ThreePidProviders.register(() -> new DnsLookupProvider(mxisd.getConfig().getMatrix(), mxisd.getServerFetcher()));
ThreePidProviders.register(() -> new ForwarderProvider(mxisd.getConfig(), mxisd.getServerFetcher()));
}
}

View File

@@ -49,10 +49,7 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
public RecursivePriorityLookupStrategy(MxisdConfig.Lookup cfg, List<? extends IThreePidProvider> providers, IBridgeFetcher bridge) {
this.cfg = cfg;
this.bridge = bridge;
this.providers = providers.stream().filter(p -> {
log.info("3PID Provider {} is enabled: {}", p.getClass().getSimpleName(), p.isEnabled());
return p.isEnabled();
}).collect(Collectors.toList());
this.providers = new ArrayList<>(providers);
try {
log.info("Found {} providers", providers.size());
@@ -114,11 +111,11 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
@Override
public List<IThreePidProvider> getLocalProviders() {
return providers.stream().filter(iThreePidProvider -> iThreePidProvider.isEnabled() && iThreePidProvider.isLocal()).collect(Collectors.toList());
return providers.stream().filter(IThreePidProvider::isLocal).collect(Collectors.toList());
}
public List<IThreePidProvider> getRemoteProviders() {
return providers.stream().filter(iThreePidProvider -> iThreePidProvider.isEnabled() && !iThreePidProvider.isLocal()).collect(Collectors.toList());
return providers.stream().filter(iThreePidProvider -> !iThreePidProvider.isLocal()).collect(Collectors.toList());
}
private static SingleLookupRequest build(String medium, String address) {

View File

@@ -24,7 +24,7 @@ import io.kamax.mxisd.as.IMatrixIdInvite;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
public interface INotificationHandler {
public interface NotificationHandler {
String getId();

View File

@@ -0,0 +1,29 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.notification;
import io.kamax.mxisd.Mxisd;
import java.util.function.Consumer;
public interface NotificationHandlerSupplier extends Consumer<Mxisd> {
}

View File

@@ -27,13 +27,13 @@ import java.util.stream.Collectors;
public class NotificationHandlers {
private static final List<Supplier<INotificationHandler>> suppliers = new ArrayList<>();
private static final List<Supplier<NotificationHandler>> suppliers = new ArrayList<>();
public static void register(Supplier<INotificationHandler> supplier) {
public static void register(Supplier<NotificationHandler> supplier) {
suppliers.add(supplier);
}
public static List<INotificationHandler> get() {
public static List<NotificationHandler> get() {
return suppliers.stream().map(Supplier::get).collect(Collectors.toList());
}

View File

@@ -37,9 +37,9 @@ public class NotificationManager {
private transient final Logger log = LoggerFactory.getLogger(NotificationManager.class);
private Map<String, INotificationHandler> handlers;
private Map<String, NotificationHandler> handlers;
public NotificationManager(NotificationConfig cfg, List<INotificationHandler> handlers) {
public NotificationManager(NotificationConfig cfg, List<NotificationHandler> handlers) {
this.handlers = new HashMap<>();
handlers.forEach(h -> {
log.info("Found handler {} for medium {}", h.getId(), h.getMedium());
@@ -53,8 +53,8 @@ public class NotificationManager {
this.handlers.forEach((k, v) -> log.info("\tHandler for {}: {}", k, v.getId()));
}
private INotificationHandler ensureMedium(String medium) {
INotificationHandler handler = handlers.get(medium);
private NotificationHandler ensureMedium(String medium) {
NotificationHandler handler = handlers.get(medium);
if (handler == null) {
throw new NotImplementedException(medium + " is not a supported 3PID medium type");
}
@@ -77,7 +77,7 @@ public class NotificationManager {
ensureMedium(session.getThreePid().getMedium()).sendForValidation(session);
}
public void sendforRemoteValidation(IThreePidSession session) {
public void sendForRemoteValidation(IThreePidSession session) {
ensureMedium(session.getThreePid().getMedium()).sendForRemoteValidation(session);
}

View File

@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@@ -54,14 +55,10 @@ public class ProfileManager {
public ProfileManager(List<? extends ProfileProvider> providers, ClientDnsOverwrite dns, CloseableHttpClient client) {
this.dns = dns;
this.client = client;
this.providers = new ArrayList<>(providers);
log.info("--- Profile providers ---");
this.providers = providers.stream()
.filter(pp -> {
log.info("\t- {} - Is enabled? {}", pp.getClass().getSimpleName(), pp.isEnabled());
return pp.isEnabled();
})
.collect(Collectors.toList());
log.info("Profile Providers:");
providers.forEach(p -> log.info("\t- {}", p.getClass().getSimpleName()));
}
public <T> List<T> getList(Function<ProfileProvider, List<T>> function) {

View File

@@ -28,8 +28,6 @@ import java.util.Optional;
public interface ProfileProvider {
boolean isEnabled();
Optional<String> getDisplayName(_MatrixID userId);
List<_ThreePid> getThreepids(_MatrixID userId);

View File

@@ -161,7 +161,7 @@ public class SessionMananger {
notifMgr.sendForValidation(session);
} else {
log.info("Session {} for {}: sending remote-only validation notification", sessionId, tpid);
notifMgr.sendforRemoteValidation(session);
notifMgr.sendForRemoteValidation(session);
}
storage.insertThreePidSession(session.getDao());

View File

@@ -20,7 +20,7 @@
package io.kamax.mxisd.threepid.connector;
public interface IThreePidConnector {
public interface ThreePidConnector {
String getId();

View File

@@ -0,0 +1,44 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.connector.email;
import com.google.gson.JsonObject;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.connector.EmailSmtpConfig;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional;
public class BuiltInEmailConnectorSupplier implements EmailConnectorSupplier {
@Override
public Optional<EmailConnector> apply(EmailConfig cfg, Mxisd mxisd) {
if (StringUtils.equals(EmailSmtpConnector.ID, cfg.getConnector())) {
EmailSmtpConfig smtpCfg = GsonUtil.get().fromJson(cfg.getConnectors().getOrDefault(EmailSmtpConnector.ID, new JsonObject()), EmailSmtpConfig.class);
return Optional.of(new EmailSmtpConnector(smtpCfg));
}
return Optional.empty();
}
}

View File

@@ -21,9 +21,9 @@
package io.kamax.mxisd.threepid.connector.email;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.threepid.connector.IThreePidConnector;
import io.kamax.mxisd.threepid.connector.ThreePidConnector;
public interface IEmailConnector extends IThreePidConnector {
public interface EmailConnector extends ThreePidConnector {
@Override
default String getMedium() {

View File

@@ -0,0 +1,31 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.connector.email;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import java.util.Optional;
import java.util.function.BiFunction;
public interface EmailConnectorSupplier extends BiFunction<EmailConfig, Mxisd, Optional<EmailConnector>> {
}

View File

@@ -40,7 +40,9 @@ import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Properties;
public class EmailSmtpConnector implements IEmailConnector {
public class EmailSmtpConnector implements EmailConnector {
public static final String ID = "smtp";
private transient final Logger log = LoggerFactory.getLogger(EmailSmtpConnector.class);
@@ -48,7 +50,7 @@ public class EmailSmtpConnector implements IEmailConnector {
private Session session;
public EmailSmtpConnector(EmailSmtpConfig cfg) {
this.cfg = cfg;
this.cfg = cfg.build();
Properties sCfg = new Properties();
sCfg.setProperty("mail.smtp.host", cfg.getHost());
@@ -68,7 +70,7 @@ public class EmailSmtpConnector implements IEmailConnector {
@Override
public String getId() {
return "smtp";
return ID;
}
@Override

View File

@@ -20,7 +20,9 @@
package io.kamax.mxisd.threepid.connector.phone;
public class BlackholePhoneConnector implements IPhoneConnector {
public class BlackholePhoneConnector implements PhoneConnector {
public static final String ID = "none";
@Override
public void send(String recipient, String content) {
@@ -29,7 +31,7 @@ public class BlackholePhoneConnector implements IPhoneConnector {
@Override
public String getId() {
return "BLACKHOLE";
return ID;
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.connector.phone;
import com.google.gson.JsonObject;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.connector.PhoneTwilioConfig;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional;
public class BuiltInPhoneConnectorSupplier implements PhoneConnectorSupplier {
@Override
public Optional<PhoneConnector> apply(PhoneConfig cfg, Mxisd mxisd) {
if (StringUtils.equals(PhoneSmsTwilioConnector.ID, cfg.getConnector())) {
PhoneTwilioConfig cCfg = GsonUtil.get().fromJson(cfg.getConnectors().getOrDefault(PhoneSmsTwilioConnector.ID, new JsonObject()), PhoneTwilioConfig.class);
return Optional.of(new PhoneSmsTwilioConnector(cCfg));
}
if (StringUtils.equals(BlackholePhoneConnector.ID, cfg.getConnector())) {
return Optional.of(new BlackholePhoneConnector());
}
return Optional.empty();
}
}

View File

@@ -21,9 +21,9 @@
package io.kamax.mxisd.threepid.connector.phone;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.threepid.connector.IThreePidConnector;
import io.kamax.mxisd.threepid.connector.ThreePidConnector;
public interface IPhoneConnector extends IThreePidConnector {
public interface PhoneConnector extends ThreePidConnector {
@Override
default String getMedium() {

View File

@@ -0,0 +1,31 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.connector.phone;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import java.util.Optional;
import java.util.function.BiFunction;
public interface PhoneConnectorSupplier extends BiFunction<PhoneConfig, Mxisd, Optional<PhoneConnector>> {
}

View File

@@ -29,14 +29,16 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PhoneSmsTwilioConnector implements IPhoneConnector {
public class PhoneSmsTwilioConnector implements PhoneConnector {
public static final String ID = "twilio";
private transient final Logger log = LoggerFactory.getLogger(PhoneSmsTwilioConnector.class);
private PhoneTwilioConfig cfg;
public PhoneSmsTwilioConnector(PhoneTwilioConfig cfg) {
this.cfg = cfg;
this.cfg = cfg.build();
Twilio.init(cfg.getAccountSid(), cfg.getAuthToken());
log.info("Twilio API has been initiated");
@@ -44,7 +46,7 @@ public class PhoneSmsTwilioConnector implements IPhoneConnector {
@Override
public String getId() {
return "twilio";
return ID;
}
@Override

View File

@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification;
package io.kamax.mxisd.threepid.generator;
import io.kamax.mxisd.as.IMatrixIdInvite;
import io.kamax.mxisd.config.MatrixConfig;
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements INotificationGenerator {
public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements NotificationGenerator {
private transient final Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class);

View File

@@ -18,13 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification;
package io.kamax.mxisd.threepid.generator;
import io.kamax.mxisd.as.IMatrixIdInvite;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
public interface INotificationGenerator {
public interface NotificationGenerator {
String getId();

View File

@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification;
package io.kamax.mxisd.threepid.generator;
import io.kamax.matrix.ThreePid;
import io.kamax.mxisd.as.IMatrixIdInvite;

View File

@@ -0,0 +1,51 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.generator.email;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import io.kamax.mxisd.config.threepid.medium.EmailTemplateConfig;
import org.apache.commons.lang.StringUtils;
import java.util.Optional;
public class BuiltInEmailGeneratorSupplier implements EmailGeneratorSupplier {
private boolean processed = false;
private EmailGenerator obj;
@Override
public Optional<EmailGenerator> apply(EmailConfig emailConfig, Mxisd mxisd) {
if (!processed) {
if (StringUtils.equals(GenericEmailNotificationGenerator.ID, emailConfig.getGenerator())) {
EmailTemplateConfig cfg = Optional.ofNullable(emailConfig.getGenerators().get(GenericEmailNotificationGenerator.ID))
.map(json -> GsonUtil.get().fromJson(json, EmailTemplateConfig.class))
.orElseGet(EmailTemplateConfig::new);
obj = new GenericEmailNotificationGenerator(cfg, emailConfig, mxisd.getConfig().getMatrix(), mxisd.getConfig().getServer());
}
}
processed = true;
return Optional.ofNullable(obj);
}
}

View File

@@ -18,12 +18,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification.email;
package io.kamax.mxisd.threepid.generator.email;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.threepid.notification.INotificationGenerator;
import io.kamax.mxisd.threepid.generator.NotificationGenerator;
public interface IEmailNotificationGenerator extends INotificationGenerator {
public interface EmailGenerator extends NotificationGenerator {
@Override
default String getMedium() {

View File

@@ -0,0 +1,31 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.generator.email;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import java.util.Optional;
import java.util.function.BiFunction;
public interface EmailGeneratorSupplier extends BiFunction<EmailConfig, Mxisd, Optional<EmailGenerator>> {
}

View File

@@ -18,27 +18,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification.email;
package io.kamax.mxisd.threepid.generator.email;
import io.kamax.matrix.ThreePid;
import io.kamax.mxisd.config.MatrixConfig;
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.threepid.notification.GenericTemplateNotificationGenerator;
import io.kamax.mxisd.threepid.generator.GenericTemplateNotificationGenerator;
public class EmailNotificationGenerator extends GenericTemplateNotificationGenerator implements IEmailNotificationGenerator {
public class GenericEmailNotificationGenerator extends GenericTemplateNotificationGenerator implements EmailGenerator {
public static final String ID = "template";
private EmailConfig cfg;
public EmailNotificationGenerator(EmailTemplateConfig templateCfg, EmailConfig cfg, MatrixConfig mxCfg, ServerConfig srvCfg) {
super(mxCfg, srvCfg, templateCfg);
public GenericEmailNotificationGenerator(EmailTemplateConfig templateCfg, EmailConfig cfg, MatrixConfig mxCfg, ServerConfig srvCfg) {
super(mxCfg, srvCfg, templateCfg.build());
this.cfg = cfg;
}
@Override
public String getId() {
return "template";
return ID;
}
@Override

View File

@@ -0,0 +1,45 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.generator.phone;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import io.kamax.mxisd.config.threepid.medium.PhoneSmsTemplateConfig;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional;
public class BuiltInPhoneGeneratorSupplier implements PhoneGeneratorSupplier {
@Override
public Optional<PhoneGenerator> apply(PhoneConfig cfg, Mxisd mxisd) {
if (StringUtils.equals(SmsNotificationGenerator.ID, cfg.getGenerator())) {
PhoneSmsTemplateConfig genCfg = Optional.ofNullable(cfg.getGenerators().get(SmsNotificationGenerator.ID))
.map(json -> GsonUtil.get().fromJson(json, PhoneSmsTemplateConfig.class))
.orElseGet(PhoneSmsTemplateConfig::new);
return Optional.of(new SmsNotificationGenerator(mxisd.getConfig().getMatrix(), mxisd.getConfig().getServer(), genCfg));
}
return Optional.empty();
}
}

View File

@@ -18,11 +18,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification.phone;
package io.kamax.mxisd.threepid.generator.phone;
import io.kamax.mxisd.threepid.notification.INotificationGenerator;
import io.kamax.mxisd.threepid.generator.NotificationGenerator;
public interface IPhoneNotificationGenerator extends INotificationGenerator {
public interface PhoneGenerator extends NotificationGenerator {
default String getMedium() {
return "msisdn";

View File

@@ -0,0 +1,30 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.generator.phone;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import java.util.Optional;
import java.util.function.BiFunction;
public interface PhoneGeneratorSupplier extends BiFunction<PhoneConfig, Mxisd, Optional<PhoneGenerator>> {
}

View File

@@ -18,22 +18,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification.phone;
package io.kamax.mxisd.threepid.generator.phone;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.config.threepid.medium.PhoneSmsTemplateConfig;
import io.kamax.mxisd.threepid.notification.GenericTemplateNotificationGenerator;
import io.kamax.mxisd.threepid.generator.GenericTemplateNotificationGenerator;
public class SmsNotificationGenerator extends GenericTemplateNotificationGenerator implements IPhoneNotificationGenerator {
public class SmsNotificationGenerator extends GenericTemplateNotificationGenerator implements PhoneGenerator {
public static final String ID = "template";
public SmsNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, PhoneSmsTemplateConfig cfg) {
super(mxCfg, srvCfg, cfg);
super(mxCfg, srvCfg, cfg.build());
}
@Override
public String getId() {
return "template";
return ID;
}
}

View File

@@ -0,0 +1,131 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.notification;
import com.google.gson.JsonObject;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import io.kamax.mxisd.exception.ConfigurationException;
import io.kamax.mxisd.notification.NotificationHandlerSupplier;
import io.kamax.mxisd.notification.NotificationHandlers;
import io.kamax.mxisd.threepid.connector.email.EmailConnector;
import io.kamax.mxisd.threepid.connector.email.EmailConnectorSupplier;
import io.kamax.mxisd.threepid.connector.phone.PhoneConnector;
import io.kamax.mxisd.threepid.connector.phone.PhoneConnectorSupplier;
import io.kamax.mxisd.threepid.generator.email.EmailGenerator;
import io.kamax.mxisd.threepid.generator.email.EmailGeneratorSupplier;
import io.kamax.mxisd.threepid.generator.phone.PhoneGenerator;
import io.kamax.mxisd.threepid.generator.phone.PhoneGeneratorSupplier;
import io.kamax.mxisd.threepid.notification.email.EmailRawNotificationHandler;
import io.kamax.mxisd.threepid.notification.email.EmailSendGridNotificationHandler;
import io.kamax.mxisd.threepid.notification.phone.PhoneNotificationHandler;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class BuiltInNotificationHandlerSupplier implements NotificationHandlerSupplier {
@Override
public void accept(Mxisd mxisd) {
String emailHandler = mxisd.getConfig().getNotification().getHandler().get(ThreePidMedium.Email.getId());
acceptEmail(emailHandler, mxisd);
String phoneHandler = mxisd.getConfig().getNotification().getHandler().get(ThreePidMedium.PhoneNumber.getId());
acceptPhone(phoneHandler, mxisd);
}
private void acceptEmail(String handler, Mxisd mxisd) {
if (StringUtils.equals(EmailRawNotificationHandler.ID, handler)) {
JsonObject emailCfgJson = mxisd.getConfig().getThreepid().getMedium().get(ThreePidMedium.Email.getId());
if (Objects.nonNull(emailCfgJson)) {
EmailConfig emailCfg = GsonUtil.get().fromJson(emailCfgJson, EmailConfig.class);
if (org.apache.commons.lang.StringUtils.isBlank(emailCfg.getGenerator())) {
throw new ConfigurationException("notification.email.generator");
}
if (org.apache.commons.lang.StringUtils.isBlank(emailCfg.getConnector())) {
throw new ConfigurationException("notification.email.connector");
}
List<EmailGenerator> generators = StreamSupport
.stream(ServiceLoader.load(EmailGeneratorSupplier.class).spliterator(), false)
.map(s -> s.apply(emailCfg, mxisd))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
List<EmailConnector> connectors = StreamSupport
.stream(ServiceLoader.load(EmailConnectorSupplier.class).spliterator(), false)
.map(s -> s.apply(emailCfg, mxisd))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
NotificationHandlers.register(() -> new EmailRawNotificationHandler(emailCfg, generators, connectors));
}
}
if (StringUtils.equals(EmailSendGridNotificationHandler.ID, handler)) {
JsonObject cfgJson = mxisd.getConfig().getNotification().getHandlers().get(EmailSendGridNotificationHandler.ID);
if (Objects.nonNull(cfgJson)) {
EmailSendGridConfig cfg = GsonUtil.get().fromJson(cfgJson, EmailSendGridConfig.class);
NotificationHandlers.register(() -> new EmailSendGridNotificationHandler(mxisd.getConfig(), cfg));
}
}
}
private void acceptPhone(String handler, Mxisd mxisd) {
if (StringUtils.equals(PhoneNotificationHandler.ID, handler)) {
JsonObject cfgJson = mxisd.getConfig().getThreepid().getMedium().get(ThreePidMedium.PhoneNumber.getId());
if (Objects.nonNull(cfgJson)) {
PhoneConfig cfg = GsonUtil.get().fromJson(cfgJson, PhoneConfig.class);
List<PhoneGenerator> generators = StreamSupport
.stream(ServiceLoader.load(PhoneGeneratorSupplier.class).spliterator(), false)
.map(s -> s.apply(cfg, mxisd))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
List<PhoneConnector> connectors = StreamSupport
.stream(ServiceLoader.load(PhoneConnectorSupplier.class).spliterator(), false)
.map(s -> s.apply(cfg, mxisd))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
NotificationHandlers.register(() -> new PhoneNotificationHandler(cfg, generators, connectors));
}
}
}
}

View File

@@ -23,14 +23,15 @@ package io.kamax.mxisd.threepid.notification;
import io.kamax.mxisd.as.IMatrixIdInvite;
import io.kamax.mxisd.exception.ConfigurationException;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.notification.INotificationHandler;
import io.kamax.mxisd.threepid.connector.IThreePidConnector;
import io.kamax.mxisd.notification.NotificationHandler;
import io.kamax.mxisd.threepid.connector.ThreePidConnector;
import io.kamax.mxisd.threepid.generator.NotificationGenerator;
import io.kamax.mxisd.threepid.session.IThreePidSession;
import org.apache.commons.lang.StringUtils;
import java.util.List;
public abstract class GenericNotificationHandler<A extends IThreePidConnector, B extends INotificationGenerator> implements INotificationHandler {
public abstract class GenericNotificationHandler<A extends ThreePidConnector, B extends NotificationGenerator> implements NotificationHandler {
private A connector;
private B generator;

View File

@@ -22,23 +22,26 @@ package io.kamax.mxisd.threepid.notification.email;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
import io.kamax.mxisd.threepid.connector.email.IEmailConnector;
import io.kamax.mxisd.threepid.connector.email.EmailConnector;
import io.kamax.mxisd.threepid.generator.email.EmailGenerator;
import io.kamax.mxisd.threepid.notification.GenericNotificationHandler;
import java.util.List;
public class EmailRawNotificationHandler extends GenericNotificationHandler<IEmailConnector, IEmailNotificationGenerator> {
public class EmailRawNotificationHandler extends GenericNotificationHandler<EmailConnector, EmailGenerator> {
public static final String ID = "raw";
private EmailConfig cfg;
public EmailRawNotificationHandler(EmailConfig cfg, List<IEmailNotificationGenerator> generators, List<IEmailConnector> connectors) {
public EmailRawNotificationHandler(EmailConfig cfg, List<EmailGenerator> generators, List<EmailConnector> connectors) {
this.cfg = cfg;
process(connectors, generators);
}
@Override
public String getId() {
return "raw";
return ID;
}
@Override
@@ -57,7 +60,7 @@ public class EmailRawNotificationHandler extends GenericNotificationHandler<IEma
}
@Override
protected void send(IEmailConnector connector, String recipient, String content) {
protected void send(EmailConnector connector, String recipient, String content) {
connector.send(
cfg.getIdentity().getFrom(),
cfg.getIdentity().getName(),

View File

@@ -18,19 +18,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.threepid.connector.email;
package io.kamax.mxisd.threepid.notification.email;
import com.sendgrid.SendGrid;
import com.sendgrid.SendGridException;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.as.IMatrixIdInvite;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig;
import io.kamax.mxisd.exception.FeatureNotAvailable;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.notification.INotificationHandler;
import io.kamax.mxisd.threepid.notification.PlaceholderNotificationGenerator;
import io.kamax.mxisd.notification.NotificationHandler;
import io.kamax.mxisd.threepid.generator.PlaceholderNotificationGenerator;
import io.kamax.mxisd.threepid.session.IThreePidSession;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
@@ -45,22 +44,24 @@ import static com.sendgrid.SendGrid.Email;
import static com.sendgrid.SendGrid.Response;
import static io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig.EmailTemplate;
public class EmailSendGridNotificationHandler extends PlaceholderNotificationGenerator implements INotificationHandler {
public class EmailSendGridNotificationHandler extends PlaceholderNotificationGenerator implements NotificationHandler {
public static final String ID = "sendgrid";
private transient final Logger log = LoggerFactory.getLogger(EmailSendGridNotificationHandler.class);
private EmailSendGridConfig cfg;
private SendGrid sendgrid;
public EmailSendGridNotificationHandler(MatrixConfig mxCfg, ServerConfig srvCfg, EmailSendGridConfig cfg) {
super(mxCfg, srvCfg);
public EmailSendGridNotificationHandler(MxisdConfig mCfg, EmailSendGridConfig cfg) {
super(mCfg.getMatrix(), mCfg.getServer());
this.cfg = cfg;
this.sendgrid = new SendGrid(cfg.getApi().getKey());
}
@Override
public String getId() {
return "sendgrid";
return ID;
}
@Override

View File

@@ -22,23 +22,26 @@ package io.kamax.mxisd.threepid.notification.phone;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.config.threepid.medium.PhoneConfig;
import io.kamax.mxisd.threepid.connector.phone.IPhoneConnector;
import io.kamax.mxisd.threepid.connector.phone.PhoneConnector;
import io.kamax.mxisd.threepid.generator.phone.PhoneGenerator;
import io.kamax.mxisd.threepid.notification.GenericNotificationHandler;
import java.util.List;
public class PhoneNotificationHandler extends GenericNotificationHandler<IPhoneConnector, IPhoneNotificationGenerator> {
public class PhoneNotificationHandler extends GenericNotificationHandler<PhoneConnector, PhoneGenerator> {
public static final String ID = "raw";
private PhoneConfig cfg;
public PhoneNotificationHandler(PhoneConfig cfg, List<IPhoneConnector> connectors, List<IPhoneNotificationGenerator> generators) {
public PhoneNotificationHandler(PhoneConfig cfg, List<PhoneGenerator> generators, List<PhoneConnector> connectors) {
this.cfg = cfg;
process(connectors, generators);
}
@Override
public String getId() {
return "raw";
return ID;
}
@Override
@@ -57,7 +60,7 @@ public class PhoneNotificationHandler extends GenericNotificationHandler<IPhoneC
}
@Override
protected void send(IPhoneConnector connector, String recipient, String content) {
protected void send(PhoneConnector connector, String recipient, String content) {
connector.send(recipient, content);
}

View File

@@ -59,6 +59,7 @@ public class ThreePidSession implements IThreePidSession {
dao.getNextLink(),
dao.getToken()
);
timestamp = Instant.ofEpochMilli(dao.getCreationTime());
isValidated = dao.getValidated();
if (isValidated) {
@@ -81,7 +82,6 @@ public class ThreePidSession implements IThreePidSession {
this.attempt = attempt;
this.nextLink = nextLink;
this.token = token;
this.timestamp = Instant.now();
}

View File

@@ -7,3 +7,4 @@ io.kamax.mxisd.backend.rest.RestStoreSupplier
io.kamax.mxisd.backend.sql.generic.GenericSqlStoreSupplier
io.kamax.mxisd.backend.sql.synapse.SynapseSqlStoreSupplier
io.kamax.mxisd.backend.wordpress.WordpressStoreSupplier
io.kamax.mxisd.lookup.provider.RemoteLookupProviderSupplier

View File

@@ -0,0 +1 @@
io.kamax.mxisd.threepid.notification.BuiltInNotificationHandlerSupplier

View File

@@ -0,0 +1 @@
io.kamax.mxisd.threepid.connector.email.BuiltInEmailConnectorSupplier

View File

@@ -0,0 +1 @@
io.kamax.mxisd.threepid.connector.phone.BuiltInPhoneConnectorSupplier

View File

@@ -0,0 +1 @@
io.kamax.mxisd.threepid.generator.email.BuiltInEmailGeneratorSupplier

View File

@@ -0,0 +1 @@
io.kamax.mxisd.threepid.generator.phone.BuiltInPhoneGeneratorSupplier

View File

@@ -1,2 +0,0 @@
org.springframework.boot.diagnostics.FailureAnalyzer=\
io.kamax.mxisd.spring.ConfigurationFailureAnalyzer

View File

@@ -0,0 +1,51 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.test;
import io.kamax.matrix.ThreePidMedium;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.MxisdConfig;
import org.junit.Test;
import static junit.framework.TestCase.*;
public class MxisdDefaultTest {
private final String domain = "localhost";
@Test
public void defaultConfig() {
MxisdConfig cfg = new MxisdConfig();
cfg.getMatrix().setDomain(domain);
cfg.getKey().setPath(":memory:");
cfg.getStorage().getProvider().getSqlite().setDatabase(":memory:");
Mxisd m = new Mxisd(cfg);
m.start();
assertNotNull(m.getConfig());
assertEquals(domain, m.getConfig().getMatrix().getDomain());
assertTrue(m.getNotif().isMediumSupported(ThreePidMedium.Email.getId()));
assertTrue(m.getNotif().isMediumSupported(ThreePidMedium.PhoneNumber.getId()));
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.test;
import io.kamax.mxisd.Mxisd;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.config.memory.MemoryIdentityConfig;
import io.kamax.mxisd.config.memory.MemoryThreePid;
import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Optional;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
public class MxisdTest {
private Mxisd m;
@Before
public void before() {
MxisdConfig cfg = new MxisdConfig();
cfg.getMatrix().setDomain("localhost");
cfg.getKey().setPath(":memory:");
cfg.getStorage().getProvider().getSqlite().setDatabase(":memory:");
MemoryThreePid mem3pid = new MemoryThreePid();
mem3pid.setMedium("email");
mem3pid.setAddress("john@localhost");
MemoryIdentityConfig memCfg = new MemoryIdentityConfig();
memCfg.setUsername("john");
memCfg.getThreepids().add(mem3pid);
cfg.getMemory().setEnabled(true);
cfg.getMemory().getIdentities().add(memCfg);
m = new Mxisd(cfg);
m.start();
}
@After
public void after() {
m.stop();
}
@Test
public void singleLookup() {
SingleLookupRequest req = new SingleLookupRequest();
req.setRecursive(false);
req.setType("email");
req.setThreePid("john@localhost");
Optional<SingleLookupReply> reply = m.getIdentity().find(req);
assertTrue(reply.isPresent());
assertEquals("@john:localhost", reply.get().getMxid().getId());
}
}

View File

@@ -68,7 +68,6 @@ public class ExecDirectoryStoreTest extends ExecStoreTest {
private ExecDirectoryStore getStore(ExecConfig.Directory cfg) {
ExecDirectoryStore store = new ExecDirectoryStore(cfg, getMatrixCfg());
store.setExecutorSupplier(this::build);
assertTrue(store.isEnabled());
return store;
}

View File

@@ -75,7 +75,7 @@ public class ExecIdentityStoreTest extends ExecStoreTest {
private ExecIdentityStore getStore(ExecConfig.Identity cfg) {
ExecIdentityStore store = new ExecIdentityStore(cfg, getMatrixCfg());
store.setExecutorSupplier(this::build);
assertTrue(store.isEnabled());
assertTrue(store.isLocal());
return store;
}

View File

@@ -84,7 +84,6 @@ public class ExecProfileStoreTest extends ExecStoreTest {
private ExecProfileStore getStore(ExecConfig.Profile cfg) {
ExecProfileStore store = new ExecProfileStore(cfg);
store.setExecutorSupplier(this::build);
assertTrue(store.isEnabled());
return store;
}

View File

@@ -75,22 +75,22 @@ public class LdapAuthTest {
@Test
public void singleDn() {
MatrixConfig mxCfg = new MatrixConfig();
mxCfg.setDomain(domain);
mxCfg.build();
LdapConfig cfg = new GenericLdapConfig();
cfg.getConnection().setHost(host);
cfg.getConnection().setPort(65001);
cfg.getConnection().setBaseDn(dnList.get(0));
cfg.getConnection().setBindDn(mxisdCn);
cfg.getConnection().setBindPassword(mxisdPw);
cfg.build();
LdapConfig.UID uid = new LdapConfig.UID();
uid.setType(idType);
uid.setValue(idAttribute);
cfg.getAttribute().setUid(uid);
cfg.build();
MatrixConfig mxCfg = new MatrixConfig();
mxCfg.setDomain(domain);
mxCfg.build();
LdapAuthProvider p = new LdapAuthProvider(cfg, mxCfg);
BackendAuthResult result = p.authenticate(MatrixID.from(userId, domain).valid(), userPw);