diff --git a/.gitignore b/.gitignore index 93fc794..f48e92d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ out/ # Local dev config /application.yaml +/mxisd.yaml # Local dev storage /mxisd.db diff --git a/build.gradle b/build.gradle index fd111b0..b5699a7 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,9 @@ import java.util.regex.Pattern apply plugin: 'java' -apply plugin: 'org.springframework.boot' +apply plugin: 'application' +apply plugin: 'com.github.johnrengelman.shadow' +apply plugin: 'idea' def confFileName = "application.example.yaml" def distDir = "${project.buildDir}/dist" @@ -43,6 +45,9 @@ def debBuildSystemdPath = "${debBuildBasePath}${debSystemdPath}" def dockerImageName = "kamax/mxisd" def dockerImageTag = "${dockerImageName}:${mxisdVersion()}" +group = 'io.kamax' +mainClassName = 'io.kamax.mxisd.MxisdStandaloneExec' + String mxisdVersion() { def versionPattern = Pattern.compile("v(\\d+\\.)?(\\d+\\.)?(\\d+)(-.*)?") @@ -64,16 +69,16 @@ String gitVersion() { buildscript { repositories { - mavenCentral() + jcenter() } dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.3.RELEASE' + classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.3' } } repositories { - mavenCentral() + jcenter() maven { url "https://kamax.io/maven/releases/" } maven { url "https://kamax.io/maven/snapshots/" } } @@ -81,12 +86,9 @@ repositories { dependencies { // Easy file management compile 'commons-io:commons-io:2.5' - - // Spring Boot - standalone app - compile 'org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE' - - // Thymeleaf for HTML templates - compile "org.springframework.boot:spring-boot-starter-thymeleaf:1.5.10.RELEASE" + + // Config management + compile 'org.yaml:snakeyaml:1.23' // Matrix Java SDK compile 'io.kamax:matrix-java-sdk:0.0.14-8-g0e57ec6' @@ -137,17 +139,18 @@ dependencies { // ZT-Exec for exec identity store compile 'org.zeroturnaround:zt-exec:1.10' + // HTTP server + compile 'io.undertow:undertow-core:2.0.16.Final' + testCompile 'junit:junit:4.12' testCompile 'com.github.tomakehurst:wiremock:2.8.0' testCompile 'com.unboundid:unboundid-ldapsdk:4.0.9' } -springBoot { - executable = true - - embeddedLaunchScriptProperties = [ - confFolder: "/etc/default" - ] +shadowJar { + baseName = project.name + classifier = null + version = null } processResources { diff --git a/src/main/java/io/kamax/mxisd/Mxisd.java b/src/main/java/io/kamax/mxisd/Mxisd.java new file mode 100644 index 0000000..d20ec29 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/Mxisd.java @@ -0,0 +1,193 @@ +/* + * 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; + +import io.kamax.matrix.crypto.KeyManager; +import io.kamax.matrix.crypto.SignatureManager; +import io.kamax.mxisd.as.AppSvcManager; +import io.kamax.mxisd.auth.AuthManager; +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.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.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.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.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; + +import java.util.ServiceLoader; + +public class Mxisd { + + private MxisdConfig cfg; + + private CloseableHttpClient httpClient; + + private KeyManager keyMgr; + private 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; + + public Mxisd(MxisdConfig cfg) { + this.cfg = cfg.build(); + } + + private void build() { + httpClient = HttpClients.custom() + .setUserAgent("mxisd") + .setMaxConnPerRoute(Integer.MAX_VALUE) + .setMaxConnTotal(Integer.MAX_VALUE) + .build(); + + OrmLiteSqliteStorage storage = 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)); + } + + public MxisdConfig getConfig() { + return cfg; + } + + public CloseableHttpClient getHttpClient() { + return httpClient; + } + + public InvitationManager getInvitationManager() { + return invMgr; + } + + 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(); + } + +} diff --git a/src/main/java/io/kamax/mxisd/controller/PingController.java b/src/main/java/io/kamax/mxisd/MxisdStandaloneExec.java similarity index 61% rename from src/main/java/io/kamax/mxisd/controller/PingController.java rename to src/main/java/io/kamax/mxisd/MxisdStandaloneExec.java index 406a816..f75082d 100644 --- a/src/main/java/io/kamax/mxisd/controller/PingController.java +++ b/src/main/java/io/kamax/mxisd/MxisdStandaloneExec.java @@ -18,21 +18,18 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller; +package io.kamax.mxisd; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.config.YamlConfigLoader; -@RestController -@CrossOrigin -@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class PingController { +import java.io.IOException; - @RequestMapping(value = "/_matrix/identity/api/v1") - public String ping() { - return "{}"; +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(); } } diff --git a/src/main/java/io/kamax/mxisd/as/AppServiceHandler.java b/src/main/java/io/kamax/mxisd/as/AppSvcManager.java similarity index 87% rename from src/main/java/io/kamax/mxisd/as/AppServiceHandler.java rename to src/main/java/io/kamax/mxisd/as/AppSvcManager.java index 9444564..1dedac5 100644 --- a/src/main/java/io/kamax/mxisd/as/AppServiceHandler.java +++ b/src/main/java/io/kamax/mxisd/as/AppSvcManager.java @@ -28,8 +28,10 @@ import io.kamax.matrix._ThreePid; import io.kamax.matrix.event.EventKey; import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.backend.sql.synapse.Synapse; -import io.kamax.mxisd.config.ListenerConfig; import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.exception.HttpMatrixException; +import io.kamax.mxisd.exception.NotAllowedException; import io.kamax.mxisd.notification.NotificationManager; import io.kamax.mxisd.profile.ProfileManager; import io.kamax.mxisd.storage.IStorage; @@ -38,8 +40,6 @@ import io.kamax.mxisd.util.GsonParser; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.InputStream; import java.time.Instant; @@ -48,14 +48,12 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -@Component -public class AppServiceHandler { +public class AppSvcManager { - private final Logger log = LoggerFactory.getLogger(AppServiceHandler.class); + private transient final Logger log = LoggerFactory.getLogger(AppSvcManager.class); private final GsonParser parser; - private String localpart; private MatrixConfig cfg; private IStorage store; private ProfileManager profiler; @@ -64,22 +62,36 @@ public class AppServiceHandler { private Map> transactionsInProgress; - @Autowired - public AppServiceHandler(ListenerConfig lCfg, MatrixConfig cfg, IStorage store, ProfileManager profiler, NotificationManager notif, Synapse synapse) { - this.cfg = cfg; + public AppSvcManager(MxisdConfig cfg, IStorage store, ProfileManager profiler, NotificationManager notif, Synapse synapse) { + this.cfg = cfg.getMatrix(); this.store = store; this.profiler = profiler; this.notif = notif; this.synapse = synapse; - localpart = lCfg.getLocalpart(); parser = new GsonParser(); transactionsInProgress = new ConcurrentHashMap<>(); } + public AppSvcManager withToken(String token) { + if (StringUtils.isBlank(token)) { + throw new HttpMatrixException(401, "M_UNAUTHORIZED", "No HS token"); + } + + if (!StringUtils.equals(cfg.getListener().getToken().getHs(), token)) { + throw new NotAllowedException("Invalid HS token"); + } + + return this; + } + public CompletableFuture processTransaction(String txnId, InputStream is) { + if (StringUtils.isEmpty(txnId)) { + throw new IllegalArgumentException("Transaction ID cannot be empty"); + } + synchronized (this) { - Optional dao = store.getTransactionResult(localpart, txnId); + Optional dao = store.getTransactionResult(cfg.getListener().getLocalpart(), txnId); if (dao.isPresent()) { log.info("AS Transaction {} already processed - returning computed result", txnId); return CompletableFuture.completedFuture(dao.get().getResult()); @@ -104,19 +116,19 @@ public class AppServiceHandler { log.debug("{} event(s) parsed", events.size()); processTransaction(events); - Instant end = Instant.now(); - log.info("Processed AS transaction {} in {} ms", txnId, (Instant.now().toEpochMilli() - start.toEpochMilli())); + Instant end = Instant.now(); String result = "{}"; try { log.info("Saving transaction details to store"); - store.insertTransactionResult(localpart, txnId, end, result); + store.insertTransactionResult(cfg.getListener().getLocalpart(), txnId, end, result); } finally { log.debug("Removing CompletedFuture from transaction map"); transactionsInProgress.remove(txnId); } + log.info("Processed AS transaction {} in {} ms", txnId, (Instant.now().toEpochMilli() - start.toEpochMilli())); future.complete(result); } catch (Exception e) { log.error("Unable to properly process transaction {}", txnId, e); diff --git a/src/main/java/io/kamax/mxisd/auth/AuthManager.java b/src/main/java/io/kamax/mxisd/auth/AuthManager.java index 43ea8d4..46b3b8d 100644 --- a/src/main/java/io/kamax/mxisd/auth/AuthManager.java +++ b/src/main/java/io/kamax/mxisd/auth/AuthManager.java @@ -37,6 +37,7 @@ import io.kamax.mxisd.auth.provider.AuthenticatorProvider; import io.kamax.mxisd.auth.provider.BackendAuthResult; import io.kamax.mxisd.config.AuthenticationConfig; import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.dns.ClientDnsOverwrite; import io.kamax.mxisd.exception.RemoteLoginException; import io.kamax.mxisd.invitation.InvitationManager; @@ -53,8 +54,6 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import java.io.IOException; import java.net.URI; @@ -63,7 +62,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -@Service public class AuthManager { private static final String TypeKey = "type"; @@ -74,8 +72,8 @@ public class AuthManager { private static final String UserIdTypeValue = "m.id.user"; private static final String ThreepidTypeValue = "m.id.thirdparty"; - private final Logger log = LoggerFactory.getLogger(AuthManager.class); - private final Gson gson = GsonUtil.get(); + private transient final Logger log = LoggerFactory.getLogger(AuthManager.class); + private final Gson gson = GsonUtil.get(); // FIXME replace private List providers; private MatrixConfig mxCfg; @@ -85,18 +83,16 @@ public class AuthManager { private LookupStrategy strategy; private CloseableHttpClient client; - @Autowired public AuthManager( - AuthenticationConfig cfg, - MatrixConfig mxCfg, - List providers, + MxisdConfig cfg, + List providers, LookupStrategy strategy, InvitationManager invMgr, ClientDnsOverwrite dns, CloseableHttpClient client ) { - this.cfg = cfg; - this.mxCfg = mxCfg; + this.cfg = cfg.getAuth(); + this.mxCfg = cfg.getMatrix(); this.providers = new ArrayList<>(providers); this.strategy = strategy; this.invMgr = invMgr; diff --git a/src/main/java/io/kamax/mxisd/config/ThymeleafConfig.java b/src/main/java/io/kamax/mxisd/auth/AuthProviders.java similarity index 54% rename from src/main/java/io/kamax/mxisd/config/ThymeleafConfig.java rename to src/main/java/io/kamax/mxisd/auth/AuthProviders.java index 2354a7a..93abe0a 100644 --- a/src/main/java/io/kamax/mxisd/config/ThymeleafConfig.java +++ b/src/main/java/io/kamax/mxisd/auth/AuthProviders.java @@ -18,25 +18,25 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.config; +package io.kamax.mxisd.auth; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.thymeleaf.resourceresolver.FileResourceResolver; -import org.thymeleaf.templateresolver.TemplateResolver; +import io.kamax.mxisd.auth.provider.AuthenticatorProvider; -@Configuration -public class ThymeleafConfig { +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; - @Bean - public TemplateResolver getFileSystemResolver() { - TemplateResolver resolver = new TemplateResolver(); - resolver.setPrefix(""); - resolver.setSuffix(""); - resolver.setCacheable(false); - resolver.setOrder(1); - resolver.setResourceResolver(new FileResourceResolver()); - return resolver; +public class AuthProviders { + + private static final List> suppliers = new ArrayList<>(); + + public static void register(Supplier supplier) { + suppliers.add(supplier); + } + + public static List get() { + return suppliers.stream().map(Supplier::get).collect(Collectors.toList()); } } diff --git a/src/main/java/io/kamax/mxisd/backend/IdentityStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/IdentityStoreSupplier.java new file mode 100644 index 0000000..ca553e8 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/IdentityStoreSupplier.java @@ -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 . + */ + +package io.kamax.mxisd.backend; + +import io.kamax.mxisd.Mxisd; + +import java.util.function.Consumer; + +public interface IdentityStoreSupplier extends Consumer { + +} diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java index a920ab4..ba1a144 100644 --- a/src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java @@ -33,20 +33,16 @@ import io.kamax.mxisd.exception.InternalServerError; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.Objects; import java.util.Optional; -@Component public class ExecAuthStore extends ExecStore implements AuthenticatorProvider { - private final Logger log = LoggerFactory.getLogger(ExecAuthStore.class); + private transient final Logger log = LoggerFactory.getLogger(ExecAuthStore.class); private ExecConfig.Auth cfg; - @Autowired public ExecAuthStore(ExecConfig cfg) { this.cfg = Objects.requireNonNull(cfg.getAuth()); } diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecDirectoryStore.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecDirectoryStore.java index a036fe9..a5929cf 100644 --- a/src/main/java/io/kamax/mxisd/backend/exec/ExecDirectoryStore.java +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecDirectoryStore.java @@ -24,22 +24,19 @@ import io.kamax.matrix.MatrixID; import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.config.ExecConfig; import io.kamax.mxisd.config.MatrixConfig; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; +import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.directory.IDirectoryProvider; +import io.kamax.mxisd.http.io.UserDirectorySearchRequest; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider { private ExecConfig.Directory cfg; private MatrixConfig mxCfg; - @Autowired - public ExecDirectoryStore(ExecConfig cfg, MatrixConfig mxCfg) { - this(cfg.getDirectory(), mxCfg); + public ExecDirectoryStore(MxisdConfig cfg) { + this(cfg.getExec().getDirectory(), cfg.getMatrix()); } public ExecDirectoryStore(ExecConfig.Directory cfg, MatrixConfig mxCfg) { diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java index ea5a1ba..d46a077 100644 --- a/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java @@ -40,8 +40,6 @@ import io.kamax.mxisd.lookup.provider.IThreePidProvider; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.Collections; import java.util.List; @@ -49,15 +47,13 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -@Component public class ExecIdentityStore extends ExecStore implements IThreePidProvider { - private final Logger log = LoggerFactory.getLogger(ExecIdentityStore.class); + private transient final Logger log = LoggerFactory.getLogger(ExecIdentityStore.class); private final ExecConfig.Identity cfg; private final MatrixConfig mxCfg; - @Autowired public ExecIdentityStore(ExecConfig cfg, MatrixConfig mxCfg) { this(cfg.getIdentity(), mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreSupplier.java new file mode 100644 index 0000000..9a2f650 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreSupplier.java @@ -0,0 +1,56 @@ +/* + * 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.backend.exec; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class ExecIdentityStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getExec().getAuth().isEnabled()) { + AuthProviders.register(() -> new ExecAuthStore(cfg.getExec())); + } + + if (cfg.getExec().getDirectory().isEnabled()) { + DirectoryProviders.register(() -> new ExecDirectoryStore(cfg)); + } + + if (cfg.getExec().getIdentity().isEnabled()) { + ThreePidProviders.register(() -> new ExecIdentityStore(cfg.getExec(), cfg.getMatrix())); + } + + if (cfg.getExec().getProfile().isEnabled()) { + ProfileProviders.register(() -> new ExecProfileStore(cfg.getExec())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java index 5066330..3c30b43 100644 --- a/src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java @@ -28,19 +28,15 @@ import io.kamax.mxisd.profile.JsonProfileRequest; import io.kamax.mxisd.profile.JsonProfileResult; import io.kamax.mxisd.profile.ProfileProvider; import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.Collections; import java.util.List; import java.util.Optional; -@Component public class ExecProfileStore extends ExecStore implements ProfileProvider { private ExecConfig.Profile cfg; - @Autowired public ExecProfileStore(ExecConfig cfg) { this(cfg.getProfile()); } diff --git a/src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java b/src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java index 8219e7b..055a70b 100644 --- a/src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java +++ b/src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java @@ -47,7 +47,7 @@ public class ExecStore { return GsonUtil.get().toJson(o); } - private final Logger log = LoggerFactory.getLogger(ExecStore.class); + private transient final Logger log = LoggerFactory.getLogger(ExecStore.class); private Supplier executorSupplier = () -> new ProcessExecutor().readOutput(true); diff --git a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseAuthenticator.java b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseAuthenticator.java index ea7b1a5..e7e63c5 100644 --- a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseAuthenticator.java +++ b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseAuthenticator.java @@ -29,6 +29,7 @@ import io.kamax.matrix._MatrixID; import io.kamax.mxisd.UserIdType; import io.kamax.mxisd.auth.provider.AuthenticatorProvider; import io.kamax.mxisd.auth.provider.BackendAuthResult; +import io.kamax.mxisd.config.FirebaseConfig; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,10 +39,14 @@ import java.util.concurrent.TimeUnit; public class GoogleFirebaseAuthenticator extends GoogleFirebaseBackend implements AuthenticatorProvider { - private Logger log = LoggerFactory.getLogger(GoogleFirebaseAuthenticator.class); + private transient final Logger log = LoggerFactory.getLogger(GoogleFirebaseAuthenticator.class); private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + public GoogleFirebaseAuthenticator(FirebaseConfig cfg) { + this(cfg.isEnabled(), cfg.getCredentials(), cfg.getDatabase()); + } + public GoogleFirebaseAuthenticator(boolean isEnabled, String credsPath, String db) { super(isEnabled, "AuthenticationProvider", credsPath, db); } diff --git a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseBackend.java b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseBackend.java index e5d104d..3d50c05 100644 --- a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseBackend.java @@ -35,7 +35,7 @@ import java.io.IOException; public class GoogleFirebaseBackend { - private Logger log = LoggerFactory.getLogger(GoogleFirebaseBackend.class); + private transient final Logger log = LoggerFactory.getLogger(GoogleFirebaseBackend.class); private boolean isEnabled; private FirebaseAuth fbAuth; diff --git a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseProvider.java b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseProvider.java index 4acc953..ee0e1a7 100644 --- a/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseProvider.java @@ -25,6 +25,7 @@ import com.google.firebase.tasks.OnFailureListener; import com.google.firebase.tasks.OnSuccessListener; import io.kamax.matrix.MatrixID; import io.kamax.matrix.ThreePidMedium; +import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupRequest; import io.kamax.mxisd.lookup.ThreePidMapping; @@ -40,9 +41,13 @@ import java.util.concurrent.TimeUnit; public class GoogleFirebaseProvider extends GoogleFirebaseBackend implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(GoogleFirebaseProvider.class); + private transient final Logger log = LoggerFactory.getLogger(GoogleFirebaseProvider.class); private String domain; + public GoogleFirebaseProvider(MxisdConfig cfg) { + this(cfg.getFirebase().isEnabled(), cfg.getFirebase().getCredentials(), cfg.getFirebase().getDatabase(), cfg.getMatrix().getDomain()); + } + public GoogleFirebaseProvider(boolean isEnabled, String credsPath, String db, String domain) { super(isEnabled, "ThreePidProvider", credsPath, db); this.domain = domain; diff --git a/src/main/java/io/kamax/mxisd/spring/ConfigurationFailureAnalyzer.java b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseStoreSupplier.java similarity index 52% rename from src/main/java/io/kamax/mxisd/spring/ConfigurationFailureAnalyzer.java rename to src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseStoreSupplier.java index 5edd905..e70d326 100644 --- a/src/main/java/io/kamax/mxisd/spring/ConfigurationFailureAnalyzer.java +++ b/src/main/java/io/kamax/mxisd/backend/firebase/GoogleFirebaseStoreSupplier.java @@ -1,6 +1,6 @@ /* * mxisd - Matrix Identity Server Daemon - * Copyright (C) 2017 Kamax Sarl + * Copyright (C) 2018 Kamax Sarl * * https://www.kamax.io/ * @@ -18,21 +18,26 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.spring; +package io.kamax.mxisd.backend.firebase; -import io.kamax.mxisd.exception.ConfigurationException; -import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; -import org.springframework.boot.diagnostics.FailureAnalysis; +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.lookup.ThreePidProviders; -public class ConfigurationFailureAnalyzer extends AbstractFailureAnalyzer { +public class GoogleFirebaseStoreSupplier implements IdentityStoreSupplier { @Override - protected FailureAnalysis analyze(Throwable rootFailure, ConfigurationException cause) { - String message = cause.getMessage(); - if (cause.getDetailedMessage().isPresent()) { - message += " - " + cause.getDetailedMessage().get(); + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getFirebase().isEnabled()) { + AuthProviders.register(() -> new GoogleFirebaseAuthenticator(cfg.getFirebase())); + ThreePidProviders.register(() -> new GoogleFirebaseProvider(cfg)); } - return new FailureAnalysis(message, "Double check the key value", cause); } } diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapAuthProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapAuthProvider.java index 407650e..b6d131c 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapAuthProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapAuthProvider.java @@ -43,8 +43,6 @@ import org.apache.directory.api.ldap.model.message.SearchScope; import org.apache.directory.ldap.client.api.LdapConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.HashSet; @@ -52,14 +50,12 @@ import java.util.List; import java.util.Optional; import java.util.Set; -@Component public class LdapAuthProvider extends LdapBackend implements AuthenticatorProvider { - private Logger log = LoggerFactory.getLogger(LdapAuthProvider.class); + private transient final Logger log = LoggerFactory.getLogger(LdapAuthProvider.class); private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); - @Autowired public LdapAuthProvider(LdapConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java index 78c366e..ba04a0d 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java @@ -45,7 +45,7 @@ public abstract class LdapBackend { public static final String UID = "uid"; public static final String MATRIX_ID = "mxid"; - private Logger log = LoggerFactory.getLogger(LdapBackend.class); + private transient final Logger log = LoggerFactory.getLogger(LdapBackend.class); private LdapConfig cfg; private MatrixConfig mxCfg; diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapDirectoryProvider.java index 86de7fe..cc897f0 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapDirectoryProvider.java @@ -22,9 +22,9 @@ package io.kamax.mxisd.backend.ldap; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.LdapConfig; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.directory.IDirectoryProvider; import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import io.kamax.mxisd.util.GsonUtil; import org.apache.directory.api.ldap.model.cursor.CursorException; import org.apache.directory.api.ldap.model.cursor.CursorLdapReferralException; @@ -35,19 +35,15 @@ import org.apache.directory.api.ldap.model.message.SearchScope; import org.apache.directory.ldap.client.api.LdapConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.ArrayList; import java.util.List; -@Component public class LdapDirectoryProvider extends LdapBackend implements IDirectoryProvider { - private Logger log = LoggerFactory.getLogger(LdapDirectoryProvider.class); + private transient final Logger log = LoggerFactory.getLogger(LdapDirectoryProvider.class); - @Autowired public LdapDirectoryProvider(LdapConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } @@ -95,7 +91,6 @@ public class LdapDirectoryProvider extends LdapBackend implements IDirectoryProv } } } - } catch (CursorLdapReferralException e) { log.warn("An entry is only available via referral, skipping"); } catch (IOException | LdapException | CursorException e) { diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapProfileProvider.java index 2cc0377..77fb675 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapProfileProvider.java @@ -36,8 +36,6 @@ import org.apache.directory.api.ldap.model.message.SearchScope; import org.apache.directory.ldap.client.api.LdapConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.ArrayList; @@ -45,12 +43,10 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -@Component public class LdapProfileProvider extends LdapBackend implements ProfileProvider { - private transient Logger log = LoggerFactory.getLogger(LdapProfileProvider.class); + private transient final Logger log = LoggerFactory.getLogger(LdapProfileProvider.class); - @Autowired public LdapProfileProvider(LdapConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapStoreSupplier.java new file mode 100644 index 0000000..cef492a --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapStoreSupplier.java @@ -0,0 +1,47 @@ +/* + * 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.backend.ldap; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class LdapStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getLdap().isEnabled()) { + AuthProviders.register(() -> new LdapAuthProvider(cfg.getLdap(), cfg.getMatrix())); + DirectoryProviders.register(() -> new LdapDirectoryProvider(cfg.getLdap(), cfg.getMatrix())); + ThreePidProviders.register(() -> new LdapThreePidProvider(cfg.getLdap(), cfg.getMatrix())); + ProfileProviders.register(() -> new LdapProfileProvider(cfg.getLdap(), cfg.getMatrix())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapThreePidProvider.java index 7f640f2..6f40dcf 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapThreePidProvider.java @@ -37,17 +37,15 @@ import org.apache.directory.api.ldap.model.message.SearchScope; import org.apache.directory.ldap.client.api.LdapConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Optional; -@Component public class LdapThreePidProvider extends LdapBackend implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(LdapThreePidProvider.class); + private transient final Logger log = LoggerFactory.getLogger(LdapThreePidProvider.class); public LdapThreePidProvider(LdapConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapAuthProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapAuthProvider.java index 1550e9a..8fdc77f 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapAuthProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapAuthProvider.java @@ -23,9 +23,7 @@ package io.kamax.mxisd.backend.ldap.netiq; import io.kamax.mxisd.backend.ldap.LdapAuthProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig; -import org.springframework.stereotype.Component; -@Component public class NetIqLdapAuthProvider extends LdapAuthProvider { public NetIqLdapAuthProvider(NetIqLdapConfig cfg, MatrixConfig mxCfg) { diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapDirectoryProvider.java index 226e0de..10547dd 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapDirectoryProvider.java @@ -23,9 +23,7 @@ package io.kamax.mxisd.backend.ldap.netiq; import io.kamax.mxisd.backend.ldap.LdapDirectoryProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig; -import org.springframework.stereotype.Component; -@Component public class NetIqLdapDirectoryProvider extends LdapDirectoryProvider { public NetIqLdapDirectoryProvider(NetIqLdapConfig cfg, MatrixConfig mxCfg) { diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapProfileProvider.java index f1a4e7b..4f54619 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapProfileProvider.java @@ -24,13 +24,9 @@ import io.kamax.matrix._MatrixID; import io.kamax.mxisd.backend.ldap.LdapProfileProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class NetIqLdapProfileProvider extends LdapProfileProvider { - @Autowired public NetIqLdapProfileProvider(NetIqLdapConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapStoreSupplier.java new file mode 100644 index 0000000..63d2d00 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapStoreSupplier.java @@ -0,0 +1,47 @@ +/* + * 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.backend.ldap.netiq; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class NetIqLdapStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getLdap().isEnabled()) { + AuthProviders.register(() -> new NetIqLdapAuthProvider(cfg.getNetiq(), cfg.getMatrix())); + DirectoryProviders.register(() -> new NetIqLdapDirectoryProvider(cfg.getNetiq(), cfg.getMatrix())); + ThreePidProviders.register(() -> new NetIqLdapThreePidProvider(cfg.getNetiq(), cfg.getMatrix())); + ProfileProviders.register(() -> new NetIqLdapProfileProvider(cfg.getNetiq(), cfg.getMatrix())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapThreePidProvider.java index f8c8e93..75ce646 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/netiq/NetIqLdapThreePidProvider.java @@ -23,9 +23,7 @@ package io.kamax.mxisd.backend.ldap.netiq; import io.kamax.mxisd.backend.ldap.LdapThreePidProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig; -import org.springframework.stereotype.Component; -@Component public class NetIqLdapThreePidProvider extends LdapThreePidProvider { public NetIqLdapThreePidProvider(NetIqLdapConfig cfg, MatrixConfig mxCfg) { diff --git a/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStore.java b/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStore.java index b78ba04..62eb5f7 100644 --- a/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStore.java +++ b/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStore.java @@ -31,8 +31,8 @@ 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.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.directory.IDirectoryProvider; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupRequest; import io.kamax.mxisd.lookup.ThreePidMapping; @@ -41,8 +41,6 @@ import io.kamax.mxisd.profile.ProfileProvider; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Collections; @@ -51,15 +49,13 @@ import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; -@Component public class MemoryIdentityStore implements AuthenticatorProvider, IDirectoryProvider, IThreePidProvider, ProfileProvider { - private final Logger logger = LoggerFactory.getLogger(MemoryIdentityStore.class); + private transient final Logger logger = LoggerFactory.getLogger(MemoryIdentityStore.class); private final MatrixConfig mxCfg; private final MemoryStoreConfig cfg; - @Autowired public MemoryIdentityStore(MatrixConfig mxCfg, MemoryStoreConfig cfg) { this.mxCfg = mxCfg; this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStoreSupplier.java new file mode 100644 index 0000000..92ed671 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/memory/MemoryIdentityStoreSupplier.java @@ -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 . + */ + +package io.kamax.mxisd.backend.memory; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +import java.util.function.Supplier; + +public class MemoryIdentityStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getMemory().isEnabled()) { + Supplier supplier = () -> new MemoryIdentityStore(cfg.getMatrix(), cfg.getMemory()); + + AuthProviders.register(supplier); + DirectoryProviders.register(supplier); + ThreePidProviders.register(supplier); + ProfileProviders.register(supplier); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/rest/RestAuthProvider.java b/src/main/java/io/kamax/mxisd/backend/rest/RestAuthProvider.java index 12d5a03..c70bddd 100644 --- a/src/main/java/io/kamax/mxisd/backend/rest/RestAuthProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/rest/RestAuthProvider.java @@ -27,15 +27,11 @@ import io.kamax.mxisd.config.rest.RestBackendConfig; import io.kamax.mxisd.util.RestClientUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; -@Component public class RestAuthProvider extends RestProvider implements AuthenticatorProvider { - @Autowired public RestAuthProvider(RestBackendConfig cfg) { super(cfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/rest/RestDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/rest/RestDirectoryProvider.java index a5b9f98..8649ad2 100644 --- a/src/main/java/io/kamax/mxisd/backend/rest/RestDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/rest/RestDirectoryProvider.java @@ -23,20 +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.controller.directory.v1.io.UserDirectorySearchRequest; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.directory.IDirectoryProvider; 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 org.springframework.stereotype.Component; import java.io.IOException; import java.nio.charset.StandardCharsets; -@Component public class RestDirectoryProvider extends RestProvider implements IDirectoryProvider { private MatrixConfig mxCfg; diff --git a/src/main/java/io/kamax/mxisd/backend/rest/RestProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/rest/RestProfileProvider.java index b644006..a4bf1dd 100644 --- a/src/main/java/io/kamax/mxisd/backend/rest/RestProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/rest/RestProfileProvider.java @@ -40,7 +40,6 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.io.IOException; import java.net.URISyntaxException; @@ -48,10 +47,9 @@ import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Function; -@Component public class RestProfileProvider extends RestProvider implements ProfileProvider { - private final Logger log = LoggerFactory.getLogger(RestProfileProvider.class); + private transient final Logger log = LoggerFactory.getLogger(RestProfileProvider.class); public RestProfileProvider(RestBackendConfig cfg) { super(cfg); diff --git a/src/main/java/io/kamax/mxisd/backend/rest/RestStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/rest/RestStoreSupplier.java new file mode 100644 index 0000000..6717af9 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/rest/RestStoreSupplier.java @@ -0,0 +1,47 @@ +/* + * 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.backend.rest; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class RestStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getRest().isEnabled()) { + AuthProviders.register(() -> new RestAuthProvider(cfg.getRest())); + DirectoryProviders.register(() -> new RestDirectoryProvider(cfg.getRest(), cfg.getMatrix())); + ThreePidProviders.register(() -> new RestThreePidProvider(cfg.getRest(), cfg.getMatrix())); + ProfileProviders.register(() -> new RestProfileProvider(cfg.getRest())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/rest/RestThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/rest/RestThreePidProvider.java index b1e3275..fc9edbe 100644 --- a/src/main/java/io/kamax/mxisd/backend/rest/RestThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/rest/RestThreePidProvider.java @@ -35,8 +35,6 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.ArrayList; @@ -44,14 +42,12 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -@Component public class RestThreePidProvider extends RestProvider implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(RestThreePidProvider.class); + private transient final Logger log = LoggerFactory.getLogger(RestThreePidProvider.class); private MatrixConfig mxCfg; // FIXME should be done in the lookup manager - @Autowired public RestThreePidProvider(RestBackendConfig cfg, MatrixConfig mxCfg) { super(cfg); this.mxCfg = mxCfg; diff --git a/src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java index 9cacf77..ebc17f7 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java @@ -39,7 +39,7 @@ import java.util.Optional; public abstract class SqlProfileProvider implements ProfileProvider { - private Logger log = LoggerFactory.getLogger(SqlProfileProvider.class); + private transient final Logger log = LoggerFactory.getLogger(SqlProfileProvider.class); private SqlConfig.Profile cfg; diff --git a/src/main/java/io/kamax/mxisd/backend/sql/SqlThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/SqlThreePidProvider.java index 2a77cbc..879c0ac 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/SqlThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/SqlThreePidProvider.java @@ -41,7 +41,7 @@ import java.util.Optional; public abstract class SqlThreePidProvider implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class); + private transient final Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class); private SqlConfig cfg; private MatrixConfig mxCfg; diff --git a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlAuthProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlAuthProvider.java index caae3dd..26b53ba 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlAuthProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlAuthProvider.java @@ -27,20 +27,19 @@ import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig; import io.kamax.mxisd.invitation.InvitationManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class GenericSqlAuthProvider implements AuthenticatorProvider { - private Logger log = LoggerFactory.getLogger(GenericSqlAuthProvider.class); + private transient final Logger log = LoggerFactory.getLogger(GenericSqlAuthProvider.class); - @Autowired private GenericSqlProviderConfig cfg; - - @Autowired private InvitationManager invMgr; + public GenericSqlAuthProvider(GenericSqlProviderConfig cfg, InvitationManager invMgr) { + this.cfg = cfg; + this.invMgr = invMgr; + } + @Override public boolean isEnabled() { return cfg.getAuth().isEnabled(); diff --git a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlDirectoryProvider.java index 22d6097..fa47f5b 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlDirectoryProvider.java @@ -25,9 +25,9 @@ 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.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.directory.IDirectoryProvider; import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,11 +38,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; -import static io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult.Result; +import static io.kamax.mxisd.http.io.UserDirectorySearchResult.Result; -public abstract class GenericSqlDirectoryProvider implements IDirectoryProvider { +public class GenericSqlDirectoryProvider implements IDirectoryProvider { - private Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class); + private transient final Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class); protected SqlConfig cfg; protected MatrixConfig mxCfg; diff --git a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlProfileProvider.java index bbe5ec9..dd21923 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlProfileProvider.java @@ -22,9 +22,7 @@ package io.kamax.mxisd.backend.sql.generic; import io.kamax.mxisd.backend.sql.SqlProfileProvider; import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig; -import org.springframework.stereotype.Component; -@Component public class GenericSqlProfileProvider extends SqlProfileProvider { public GenericSqlProfileProvider(GenericSqlProviderConfig cfg) { diff --git a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlStoreSupplier.java new file mode 100644 index 0000000..4983369 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlStoreSupplier.java @@ -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 . + */ + +package io.kamax.mxisd.backend.sql.generic; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class GenericSqlStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + if (mxisd.getConfig().getSql().getAuth().isEnabled()) { + AuthProviders.register(() -> new GenericSqlAuthProvider(mxisd.getConfig().getSql(), mxisd.getInvitationManager())); + } + + if (mxisd.getConfig().getSql().getDirectory().isEnabled()) { + DirectoryProviders.register(() -> new GenericSqlDirectoryProvider(mxisd.getConfig().getSql(), mxisd.getConfig().getMatrix())); + } + + if (mxisd.getConfig().getSql().getIdentity().isEnabled()) { + ThreePidProviders.register(() -> new GenericSqlThreePidProvider(mxisd.getConfig().getSql(), mxisd.getConfig().getMatrix())); + } + + if (mxisd.getConfig().getSql().getProfile().isEnabled()) { + ProfileProviders.register(() -> new GenericSqlProfileProvider(mxisd.getConfig().getSql())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlThreePidProvider.java index ddd2087..ca2063c 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/generic/GenericSqlThreePidProvider.java @@ -23,13 +23,9 @@ package io.kamax.mxisd.backend.sql.generic; import io.kamax.mxisd.backend.sql.SqlThreePidProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class GenericSqlThreePidProvider extends SqlThreePidProvider { - @Autowired public GenericSqlThreePidProvider(GenericSqlProviderConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/sql/synapse/Synapse.java b/src/main/java/io/kamax/mxisd/backend/sql/synapse/Synapse.java index c62fef1..3898d36 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/synapse/Synapse.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/synapse/Synapse.java @@ -22,19 +22,15 @@ package io.kamax.mxisd.backend.sql.synapse; import io.kamax.mxisd.backend.sql.SqlConnectionPool; import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Optional; -@Component public class Synapse { private SqlConnectionPool pool; - @Autowired public Synapse(SynapseSqlProviderConfig sqlCfg) { this.pool = new SqlConnectionPool(sqlCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlDirectoryProvider.java index bc83e81..f3c54d1 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlDirectoryProvider.java @@ -24,32 +24,15 @@ import io.kamax.mxisd.backend.sql.generic.GenericSqlDirectoryProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig; import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Objects; -@Component public class SynapseSqlDirectoryProvider extends GenericSqlDirectoryProvider { - @Autowired public SynapseSqlDirectoryProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); - } - - @Override - protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException { - stmt.setString(1, "%" + searchTerm + "%"); - } - - @PostConstruct - public void build() { - if (!isEnabled()) { - return; - } GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery(); if (Objects.isNull(queries.getName().getValue())) { @@ -60,4 +43,9 @@ public class SynapseSqlDirectoryProvider extends GenericSqlDirectoryProvider { } } + @Override + protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException { + stmt.setString(1, "%" + searchTerm + "%"); + } + } diff --git a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlProfileProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlProfileProvider.java index e32f8b8..f030856 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlProfileProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlProfileProvider.java @@ -22,13 +22,9 @@ package io.kamax.mxisd.backend.sql.synapse; import io.kamax.mxisd.backend.sql.SqlProfileProvider; import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class SynapseSqlProfileProvider extends SqlProfileProvider { - @Autowired public SynapseSqlProfileProvider(SynapseSqlProviderConfig cfg) { super(cfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlStoreSupplier.java new file mode 100644 index 0000000..018885a --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlStoreSupplier.java @@ -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 . + */ + +package io.kamax.mxisd.backend.sql.synapse; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; +import io.kamax.mxisd.profile.ProfileProviders; + +public class SynapseSqlStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd mxisd) { + accept(mxisd.getConfig()); + } + + public void accept(MxisdConfig cfg) { + if (cfg.getSynapseSql().getDirectory().isEnabled()) { + DirectoryProviders.register(() -> new SynapseSqlDirectoryProvider(cfg.getSynapseSql(), cfg.getMatrix())); + } + + if (cfg.getSynapseSql().getIdentity().isEnabled()) { + ThreePidProviders.register(() -> new SynapseSqlThreePidProvider(cfg.getSynapseSql(), cfg.getMatrix())); + } + + if (cfg.getSynapseSql().getProfile().isEnabled()) { + ProfileProviders.register(() -> new SynapseSqlProfileProvider(cfg.getSynapseSql())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlThreePidProvider.java index 1d8dd80..4a65c57 100644 --- a/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/sql/synapse/SynapseSqlThreePidProvider.java @@ -23,13 +23,9 @@ package io.kamax.mxisd.backend.sql.synapse; import io.kamax.mxisd.backend.sql.SqlThreePidProvider; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class SynapseSqlThreePidProvider extends SqlThreePidProvider { - @Autowired public SynapseSqlThreePidProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) { super(cfg, mxCfg); } diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressAuthProvider.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressAuthProvider.java index 5514158..010b50b 100644 --- a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressAuthProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressAuthProvider.java @@ -28,17 +28,13 @@ import io.kamax.mxisd.auth.provider.BackendAuthResult; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class WordpressAuthProvider implements AuthenticatorProvider { - private final Logger log = LoggerFactory.getLogger(WordpressAuthProvider.class); + private transient final Logger log = LoggerFactory.getLogger(WordpressAuthProvider.class); private WordpressRestBackend wordpress; - @Autowired public WordpressAuthProvider(WordpressRestBackend wordpress) { this.wordpress = wordpress; } diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressDirectoryProvider.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressDirectoryProvider.java index f11a6b7..f681bcc 100644 --- a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressDirectoryProvider.java @@ -23,13 +23,11 @@ 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.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.directory.IDirectoryProvider; import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.PreparedStatement; @@ -37,16 +35,14 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; -@Component public class WordpressDirectoryProvider implements IDirectoryProvider { - private final Logger log = LoggerFactory.getLogger(WordpressDirectoryProvider.class); + private transient final Logger log = LoggerFactory.getLogger(WordpressDirectoryProvider.class); private WordpressConfig cfg; private WordressSqlBackend wordpress; private MatrixConfig mxCfg; - @Autowired public WordpressDirectoryProvider(WordpressConfig cfg, WordressSqlBackend wordpress, MatrixConfig mxCfg) { this.cfg = cfg; this.wordpress = wordpress; diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressRestBackend.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressRestBackend.java index 57c592d..79f7709 100644 --- a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressRestBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressRestBackend.java @@ -34,15 +34,12 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; -@Component public class WordpressRestBackend { - private final Logger log = LoggerFactory.getLogger(WordpressRestBackend.class); + private transient final Logger log = LoggerFactory.getLogger(WordpressRestBackend.class); private final String jsonPath = "/wp-json"; private final String jwtPath = "/jwt-auth/v1"; @@ -54,7 +51,6 @@ public class WordpressRestBackend { private String token; - @Autowired public WordpressRestBackend(WordpressConfig cfg, CloseableHttpClient client) { this.cfg = cfg; this.client = client; diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressStoreSupplier.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressStoreSupplier.java new file mode 100644 index 0000000..63872b8 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressStoreSupplier.java @@ -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 . + */ + +package io.kamax.mxisd.backend.wordpress; + +import io.kamax.mxisd.Mxisd; +import io.kamax.mxisd.auth.AuthProviders; +import io.kamax.mxisd.backend.IdentityStoreSupplier; +import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.wordpress.WordpressConfig; +import io.kamax.mxisd.directory.DirectoryProviders; +import io.kamax.mxisd.lookup.ThreePidProviders; + +public class WordpressStoreSupplier implements IdentityStoreSupplier { + + @Override + public void accept(Mxisd m) { + WordpressConfig wpCfg = m.getConfig().getWordpress(); + MatrixConfig mxCfg = m.getConfig().getMatrix(); + + if (m.getConfig().getWordpress().isEnabled()) { + WordpressRestBackend restBackend = new WordpressRestBackend(wpCfg, m.getHttpClient()); + WordressSqlBackend sqlBackend = new WordressSqlBackend(wpCfg); + + AuthProviders.register(() -> new WordpressAuthProvider(restBackend)); + DirectoryProviders.register(() -> new WordpressDirectoryProvider(wpCfg, sqlBackend, mxCfg)); + ThreePidProviders.register(() -> new WordpressThreePidProvider(mxCfg, wpCfg, sqlBackend)); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressThreePidProvider.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressThreePidProvider.java index 0cfeca2..307eed0 100644 --- a/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressThreePidProvider.java +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordpressThreePidProvider.java @@ -31,8 +31,6 @@ import io.kamax.mxisd.lookup.ThreePidMapping; import io.kamax.mxisd.lookup.provider.IThreePidProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.PreparedStatement; @@ -42,16 +40,14 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -@Component public class WordpressThreePidProvider implements IThreePidProvider { - private final Logger log = LoggerFactory.getLogger(WordpressThreePidProvider.class); + private transient final Logger log = LoggerFactory.getLogger(WordpressThreePidProvider.class); private MatrixConfig mxCfg; private WordpressConfig cfg; private WordressSqlBackend wordpress; - @Autowired public WordpressThreePidProvider(MatrixConfig mxCfg, WordpressConfig cfg, WordressSqlBackend wordpress) { this.mxCfg = mxCfg; this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/backend/wordpress/WordressSqlBackend.java b/src/main/java/io/kamax/mxisd/backend/wordpress/WordressSqlBackend.java index 8ada21f..52303cd 100644 --- a/src/main/java/io/kamax/mxisd/backend/wordpress/WordressSqlBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/wordpress/WordressSqlBackend.java @@ -24,22 +24,17 @@ import com.mchange.v2.c3p0.ComboPooledDataSource; import io.kamax.mxisd.config.wordpress.WordpressConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.SQLException; -@Component public class WordressSqlBackend { - private Logger log = LoggerFactory.getLogger(WordressSqlBackend.class); + private transient final Logger log = LoggerFactory.getLogger(WordressSqlBackend.class); private WordpressConfig cfg; - private ComboPooledDataSource ds; - @Autowired public WordressSqlBackend(WordpressConfig cfg) { this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/config/AuthenticationConfig.java b/src/main/java/io/kamax/mxisd/config/AuthenticationConfig.java index 3f0d4a6..83b1a32 100644 --- a/src/main/java/io/kamax/mxisd/config/AuthenticationConfig.java +++ b/src/main/java/io/kamax/mxisd/config/AuthenticationConfig.java @@ -20,16 +20,10 @@ package io.kamax.mxisd.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -@Configuration -@ConfigurationProperties(prefix = "auth") public class AuthenticationConfig { public static class Rule { @@ -102,7 +96,6 @@ public class AuthenticationConfig { this.rewrite = rewrite; } - @PostConstruct public void build() { getRewrite().getUser().getRules().forEach(mapping -> mapping.setPattern(Pattern.compile(mapping.getRegex()))); } diff --git a/src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java b/src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java index 299eb99..5207dd2 100644 --- a/src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java +++ b/src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java @@ -20,14 +20,9 @@ package io.kamax.mxisd.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - import javax.annotation.PostConstruct; import java.util.Objects; -@Configuration -@ConfigurationProperties(prefix = "lookup.bulk") public class BulkLookupConfig { private Boolean enabled; diff --git a/src/main/java/io/kamax/mxisd/config/DirectoryConfig.java b/src/main/java/io/kamax/mxisd/config/DirectoryConfig.java index 1f4c78c..0469eaf 100644 --- a/src/main/java/io/kamax/mxisd/config/DirectoryConfig.java +++ b/src/main/java/io/kamax/mxisd/config/DirectoryConfig.java @@ -22,16 +22,12 @@ package io.kamax.mxisd.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("directory") public class DirectoryConfig { - private final transient Logger log = LoggerFactory.getLogger(DnsOverwriteConfig.class); + private final static Logger log = LoggerFactory.getLogger(DirectoryConfig.class); public static class Exclude { @@ -68,7 +64,7 @@ public class DirectoryConfig { } @PostConstruct - public void buid() { + public void build() { log.info("--- Directory config ---"); log.info("Exclude:"); log.info("\tHomeserver: {}", getExclude().getHomeserver()); diff --git a/src/main/java/io/kamax/mxisd/config/DnsOverwriteConfig.java b/src/main/java/io/kamax/mxisd/config/DnsOverwriteConfig.java index 27bc56a..d533694 100644 --- a/src/main/java/io/kamax/mxisd/config/DnsOverwriteConfig.java +++ b/src/main/java/io/kamax/mxisd/config/DnsOverwriteConfig.java @@ -24,18 +24,14 @@ import com.google.gson.Gson; import io.kamax.mxisd.util.GsonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; -@Configuration -@ConfigurationProperties("dns.overwrite") public class DnsOverwriteConfig { - private Logger log = LoggerFactory.getLogger(DnsOverwriteConfig.class); + private transient final Logger log = LoggerFactory.getLogger(DnsOverwriteConfig.class); public static class Entry { diff --git a/src/main/java/io/kamax/mxisd/config/ExecConfig.java b/src/main/java/io/kamax/mxisd/config/ExecConfig.java index 9fe9cab..6d01f69 100644 --- a/src/main/java/io/kamax/mxisd/config/ExecConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ExecConfig.java @@ -21,14 +21,10 @@ package io.kamax.mxisd.config; import org.apache.commons.lang3.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.*; -@Configuration -@ConfigurationProperties("exec") public class ExecConfig { public class IO { @@ -517,7 +513,7 @@ public class ExecConfig { } @PostConstruct - public ExecConfig compute() { + public ExecConfig build() { if (Objects.isNull(getAuth().isEnabled())) { getAuth().setEnabled(isEnabled()); } diff --git a/src/main/java/io/kamax/mxisd/config/FirebaseConfig.java b/src/main/java/io/kamax/mxisd/config/FirebaseConfig.java index 76d4fd7..7db419d 100644 --- a/src/main/java/io/kamax/mxisd/config/FirebaseConfig.java +++ b/src/main/java/io/kamax/mxisd/config/FirebaseConfig.java @@ -20,27 +20,14 @@ package io.kamax.mxisd.config; -import io.kamax.mxisd.auth.provider.AuthenticatorProvider; -import io.kamax.mxisd.backend.firebase.GoogleFirebaseAuthenticator; -import io.kamax.mxisd.backend.firebase.GoogleFirebaseProvider; -import io.kamax.mxisd.lookup.provider.IThreePidProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("firebase") public class FirebaseConfig { - private Logger log = LoggerFactory.getLogger(FirebaseConfig.class); - - @Autowired - private MatrixConfig mxCfg; + private transient final Logger log = LoggerFactory.getLogger(FirebaseConfig.class); private boolean enabled; private String credentials; @@ -80,14 +67,4 @@ public class FirebaseConfig { } } - @Bean - public AuthenticatorProvider getAuthProvider() { - return new GoogleFirebaseAuthenticator(enabled, credentials, database); - } - - @Bean - public IThreePidProvider getLookupProvider() { - return new GoogleFirebaseProvider(enabled, credentials, database, mxCfg.getDomain()); - } - } diff --git a/src/main/java/io/kamax/mxisd/config/ForwardConfig.java b/src/main/java/io/kamax/mxisd/config/ForwardConfig.java index d403a79..bce0c14 100644 --- a/src/main/java/io/kamax/mxisd/config/ForwardConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ForwardConfig.java @@ -20,14 +20,9 @@ package io.kamax.mxisd.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - import java.util.ArrayList; import java.util.List; -@Configuration -@ConfigurationProperties(prefix = "forward") public class ForwardConfig { private List servers = new ArrayList<>(); @@ -40,4 +35,8 @@ public class ForwardConfig { this.servers = servers; } + public void build() { + // no-op + } + } diff --git a/src/main/java/io/kamax/mxisd/config/InvitationConfig.java b/src/main/java/io/kamax/mxisd/config/InvitationConfig.java index 1194b4b..388e580 100644 --- a/src/main/java/io/kamax/mxisd/config/InvitationConfig.java +++ b/src/main/java/io/kamax/mxisd/config/InvitationConfig.java @@ -23,16 +23,12 @@ package io.kamax.mxisd.config; import io.kamax.mxisd.util.GsonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("invite") public class InvitationConfig { - private final Logger log = LoggerFactory.getLogger(InvitationConfig.class); + private transient final Logger log = LoggerFactory.getLogger(InvitationConfig.class); public static class Resolution { diff --git a/src/main/java/io/kamax/mxisd/config/KeyConfig.java b/src/main/java/io/kamax/mxisd/config/KeyConfig.java index 879dcfd..a22b29e 100644 --- a/src/main/java/io/kamax/mxisd/config/KeyConfig.java +++ b/src/main/java/io/kamax/mxisd/config/KeyConfig.java @@ -22,13 +22,9 @@ package io.kamax.mxisd.config; import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties(prefix = "key") public class KeyConfig { private String path; diff --git a/src/main/java/io/kamax/mxisd/config/ListenerConfig.java b/src/main/java/io/kamax/mxisd/config/ListenerConfig.java index c3c8b2d..0ce20ef 100644 --- a/src/main/java/io/kamax/mxisd/config/ListenerConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ListenerConfig.java @@ -21,15 +21,11 @@ package io.kamax.mxisd.config; import org.apache.commons.lang.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.net.MalformedURLException; import java.net.URL; -@Configuration -@ConfigurationProperties("matrix.listener") public class ListenerConfig { public static class Token { diff --git a/src/main/java/io/kamax/mxisd/config/MatrixConfig.java b/src/main/java/io/kamax/mxisd/config/MatrixConfig.java index 10e2ad2..13894b7 100644 --- a/src/main/java/io/kamax/mxisd/config/MatrixConfig.java +++ b/src/main/java/io/kamax/mxisd/config/MatrixConfig.java @@ -25,16 +25,12 @@ import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.List; import java.util.Map; -@Configuration -@ConfigurationProperties("matrix") public class MatrixConfig { public static class Identity { @@ -57,10 +53,11 @@ public class MatrixConfig { } } - private Logger log = LoggerFactory.getLogger(MatrixConfig.class); + private transient final Logger log = LoggerFactory.getLogger(MatrixConfig.class); private String domain; private Identity identity = new Identity(); + private ListenerConfig listener = new ListenerConfig(); public String getDomain() { return domain; @@ -78,6 +75,14 @@ public class MatrixConfig { this.identity = identity; } + public ListenerConfig getListener() { + return listener; + } + + public void setListener(ListenerConfig listener) { + this.listener = listener; + } + @PostConstruct public void build() { log.info("--- Matrix config ---"); diff --git a/src/main/java/io/kamax/mxisd/config/MxisdConfig.java b/src/main/java/io/kamax/mxisd/config/MxisdConfig.java new file mode 100644 index 0000000..f1a10ea --- /dev/null +++ b/src/main/java/io/kamax/mxisd/config/MxisdConfig.java @@ -0,0 +1,329 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.config; + +import com.google.gson.JsonObject; +import io.kamax.mxisd.config.ldap.generic.GenericLdapConfig; +import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig; +import io.kamax.mxisd.config.memory.MemoryStoreConfig; +import io.kamax.mxisd.config.rest.RestBackendConfig; +import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig; +import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; +import io.kamax.mxisd.config.threepid.notification.NotificationConfig; +import io.kamax.mxisd.config.wordpress.WordpressConfig; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +public class MxisdConfig { + + private static final Logger log = LoggerFactory.getLogger(MxisdConfig.class); + + public static class Dns { + + private DnsOverwriteConfig overwrite = new DnsOverwriteConfig(); + + public DnsOverwriteConfig getOverwrite() { + return overwrite; + } + + public void setOverwrite(DnsOverwriteConfig overwrite) { + this.overwrite = overwrite; + } + + } + + public static class Lookup { + + private BulkLookupConfig bulk = new BulkLookupConfig(); + private RecursiveLookupConfig recursive = new RecursiveLookupConfig(); + + public BulkLookupConfig getBulk() { + return bulk; + } + + public void setBulk(BulkLookupConfig bulk) { + this.bulk = bulk; + } + + public RecursiveLookupConfig getRecursive() { + return recursive; + } + + public void setRecursive(RecursiveLookupConfig recursive) { + this.recursive = recursive; + } + + public void build() { + getBulk().build(); + getRecursive().build(); + } + + } + + public static class Threepid { + + private Map medium = new HashMap<>(); + + public Map getMedium() { + return medium; + } + + public void setMedium(Map medium) { + this.medium = medium; + } + + } + + private AuthenticationConfig auth = new AuthenticationConfig(); + private DirectoryConfig directory = new DirectoryConfig(); + private Dns dns = new Dns(); + private ExecConfig exec = new ExecConfig(); + private FirebaseConfig firebase = new FirebaseConfig(); + private ForwardConfig forward = new ForwardConfig(); + private InvitationConfig invite = new InvitationConfig(); + private KeyConfig key = new KeyConfig(); + private GenericLdapConfig ldap = new GenericLdapConfig(); + private Lookup lookup = new Lookup(); + private MatrixConfig matrix = new MatrixConfig(); + private MemoryStoreConfig memory = new MemoryStoreConfig(); + private NotificationConfig notification = new NotificationConfig(); + private NetIqLdapConfig netiq = new NetIqLdapConfig(); + private ServerConfig server = new ServerConfig(); + private SessionConfig session = new SessionConfig(); + private StorageConfig storage = new StorageConfig(); + private RestBackendConfig rest = new RestBackendConfig(); + private GenericSqlProviderConfig sql = new GenericSqlProviderConfig(); + private SynapseSqlProviderConfig synapseSql = new SynapseSqlProviderConfig(); + private ViewConfig view = new ViewConfig(); + private WordpressConfig wordpress = new WordpressConfig(); + + public AuthenticationConfig getAuth() { + return auth; + } + + public void setAuth(AuthenticationConfig auth) { + this.auth = auth; + } + + public DirectoryConfig getDirectory() { + return directory; + } + + public void setDirectory(DirectoryConfig directory) { + this.directory = directory; + } + + public Dns getDns() { + return dns; + } + + public void setDns(Dns dns) { + this.dns = dns; + } + + public ExecConfig getExec() { + return exec; + } + + public void setExec(ExecConfig exec) { + this.exec = exec; + } + + public FirebaseConfig getFirebase() { + return firebase; + } + + public void setFirebase(FirebaseConfig firebase) { + this.firebase = firebase; + } + + public ForwardConfig getForward() { + return forward; + } + + public void setForward(ForwardConfig forward) { + this.forward = forward; + } + + public InvitationConfig getInvite() { + return invite; + } + + public void setInvite(InvitationConfig invite) { + this.invite = invite; + } + + public KeyConfig getKey() { + return key; + } + + public void setKey(KeyConfig key) { + this.key = key; + } + + public GenericLdapConfig getLdap() { + return ldap; + } + + public void setLdap(GenericLdapConfig ldap) { + this.ldap = ldap; + } + + public Lookup getLookup() { + return lookup; + } + + public void setLookup(Lookup lookup) { + this.lookup = lookup; + } + + public MatrixConfig getMatrix() { + return matrix; + } + + public void setMatrix(MatrixConfig matrix) { + this.matrix = matrix; + } + + public MemoryStoreConfig getMemory() { + return memory; + } + + public void setMemory(MemoryStoreConfig memory) { + this.memory = memory; + } + + public NotificationConfig getNotification() { + return notification; + } + + public void setNotification(NotificationConfig notification) { + this.notification = notification; + } + + public NetIqLdapConfig getNetiq() { + return netiq; + } + + public void setNetiq(NetIqLdapConfig netiq) { + this.netiq = netiq; + } + + public ServerConfig getServer() { + return server; + } + + public void setServer(ServerConfig server) { + this.server = server; + } + + public SessionConfig getSession() { + return session; + } + + public void setSession(SessionConfig session) { + this.session = session; + } + + public StorageConfig getStorage() { + return storage; + } + + public void setStorage(StorageConfig storage) { + this.storage = storage; + } + + public RestBackendConfig getRest() { + return rest; + } + + public void setRest(RestBackendConfig rest) { + this.rest = rest; + } + + public GenericSqlProviderConfig getSql() { + return sql; + } + + public void setSql(GenericSqlProviderConfig sql) { + this.sql = sql; + } + + public SynapseSqlProviderConfig getSynapseSql() { + return synapseSql; + } + + public void setSynapseSql(SynapseSqlProviderConfig synapseSql) { + this.synapseSql = synapseSql; + } + + public ViewConfig getView() { + return view; + } + + public void setView(ViewConfig view) { + this.view = view; + } + + public WordpressConfig getWordpress() { + return wordpress; + } + + public void setWordpress(WordpressConfig wordpress) { + this.wordpress = wordpress; + } + + public MxisdConfig build() { + if (StringUtils.isBlank(getServer().getName())) { + getServer().setName(getMatrix().getDomain()); + log.debug("server.name is empty, using matrix.domain"); + } + + getAuth().build(); + getDirectory().build(); + getExec().build(); + getFirebase().build(); + getForward().build(); + getInvite().build(); + getKey().build(); + getLdap().build(); + getLookup().build(); + getMatrix().build(); + getMemory().build(); + getNetiq().build(); + getNotification().build(); + getRest().build(); + getSession().build(); + getServer().build(); + getSql().build(); + getStorage().build(); + getSynapseSql().build(); + getView().build(); + getWordpress().build(); + + return this; + } + +} diff --git a/src/main/java/io/kamax/mxisd/config/RecursiveLookupBridgeConfig.java b/src/main/java/io/kamax/mxisd/config/RecursiveLookupBridgeConfig.java index 2514b18..358c25a 100644 --- a/src/main/java/io/kamax/mxisd/config/RecursiveLookupBridgeConfig.java +++ b/src/main/java/io/kamax/mxisd/config/RecursiveLookupBridgeConfig.java @@ -22,18 +22,14 @@ package io.kamax.mxisd.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; -@Configuration -@ConfigurationProperties(prefix = "lookup.recursive.bridge") public class RecursiveLookupBridgeConfig { - private Logger log = LoggerFactory.getLogger(RecursiveLookupBridgeConfig.class); + private transient final Logger log = LoggerFactory.getLogger(RecursiveLookupBridgeConfig.class); private boolean enabled; private boolean recursiveOnly; diff --git a/src/main/java/io/kamax/mxisd/config/RecursiveLookupConfig.java b/src/main/java/io/kamax/mxisd/config/RecursiveLookupConfig.java index f3d43f7..a7915d2 100644 --- a/src/main/java/io/kamax/mxisd/config/RecursiveLookupConfig.java +++ b/src/main/java/io/kamax/mxisd/config/RecursiveLookupConfig.java @@ -20,18 +20,14 @@ package io.kamax.mxisd.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - +import java.util.ArrayList; import java.util.List; -@Configuration -@ConfigurationProperties(prefix = "lookup.recursive") public class RecursiveLookupConfig { private boolean enabled; - private List allowedCidr; - private RecursiveLookupBridgeConfig bridge; + private List allowedCidr = new ArrayList<>(); + private RecursiveLookupBridgeConfig bridge = new RecursiveLookupBridgeConfig(); public boolean isEnabled() { return enabled; @@ -57,4 +53,8 @@ public class RecursiveLookupConfig { this.bridge = bridge; } + public void build() { + // no-op + } + } diff --git a/src/main/java/io/kamax/mxisd/config/SQLiteStorageConfig.java b/src/main/java/io/kamax/mxisd/config/SQLiteStorageConfig.java index 8ad34b1..76083f1 100644 --- a/src/main/java/io/kamax/mxisd/config/SQLiteStorageConfig.java +++ b/src/main/java/io/kamax/mxisd/config/SQLiteStorageConfig.java @@ -20,11 +20,6 @@ package io.kamax.mxisd.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConfigurationProperties("storage.provider.sqlite") public class SQLiteStorageConfig { private String database; diff --git a/src/main/java/io/kamax/mxisd/config/ServerConfig.java b/src/main/java/io/kamax/mxisd/config/ServerConfig.java index d035e64..7937ed6 100644 --- a/src/main/java/io/kamax/mxisd/config/ServerConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ServerConfig.java @@ -23,25 +23,17 @@ package io.kamax.mxisd.config; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.net.MalformedURLException; import java.net.URL; -@Configuration -@ConfigurationProperties(prefix = "server") public class ServerConfig { - private Logger log = LoggerFactory.getLogger(ServerConfig.class); - - @Autowired - private MatrixConfig mxCfg; + private transient final Logger log = LoggerFactory.getLogger(ServerConfig.class); private String name; - private int port; + private int port = 8090; private String publicUrl; public String getName() { @@ -72,11 +64,6 @@ public class ServerConfig { public void build() { log.info("--- Server config ---"); - if (StringUtils.isBlank(getName())) { - setName(mxCfg.getDomain()); - log.debug("server.name is empty, using matrix.domain"); - } - if (StringUtils.isBlank(getPublicUrl())) { setPublicUrl("https://" + getName()); log.debug("Public URL is empty, generating from name"); diff --git a/src/main/java/io/kamax/mxisd/config/SessionConfig.java b/src/main/java/io/kamax/mxisd/config/SessionConfig.java index a97e62f..78f3a2b 100644 --- a/src/main/java/io/kamax/mxisd/config/SessionConfig.java +++ b/src/main/java/io/kamax/mxisd/config/SessionConfig.java @@ -23,17 +23,12 @@ package io.kamax.mxisd.config; import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("session") public class SessionConfig { - private static Logger log = LoggerFactory.getLogger(SessionConfig.class); + private transient final Logger log = LoggerFactory.getLogger(SessionConfig.class); public static class Policy { @@ -144,18 +139,8 @@ public class SessionConfig { } - private MatrixConfig mxCfg; private Policy policy = new Policy(); - @Autowired - public SessionConfig(MatrixConfig mxCfg) { - this.mxCfg = mxCfg; - } - - public MatrixConfig getMatrixCfg() { - return mxCfg; - } - public Policy getPolicy() { return policy; } diff --git a/src/main/java/io/kamax/mxisd/config/StorageConfig.java b/src/main/java/io/kamax/mxisd/config/StorageConfig.java index cbe95f7..15f5108 100644 --- a/src/main/java/io/kamax/mxisd/config/StorageConfig.java +++ b/src/main/java/io/kamax/mxisd/config/StorageConfig.java @@ -22,16 +22,27 @@ package io.kamax.mxisd.config; import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("storage") public class StorageConfig { - private String backend; + public static class Provider { + + private SQLiteStorageConfig sqlite = new SQLiteStorageConfig(); + + public SQLiteStorageConfig getSqlite() { + return sqlite; + } + + public void setSqlite(SQLiteStorageConfig sqlite) { + this.sqlite = sqlite; + } + + } + + private String backend = "sqlite"; + private Provider provider = new Provider(); public String getBackend() { return backend; @@ -41,8 +52,16 @@ public class StorageConfig { this.backend = backend; } + public Provider getProvider() { + return provider; + } + + public void setProvider(Provider provider) { + this.provider = provider; + } + @PostConstruct - private void postConstruct() { + public void build() { if (StringUtils.isBlank(getBackend())) { throw new ConfigurationException("storage.backend"); } diff --git a/src/main/java/io/kamax/mxisd/config/ViewConfig.java b/src/main/java/io/kamax/mxisd/config/ViewConfig.java index bbd1bde..39330d5 100644 --- a/src/main/java/io/kamax/mxisd/config/ViewConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ViewConfig.java @@ -20,19 +20,15 @@ package io.kamax.mxisd.config; -import com.google.gson.Gson; +import io.kamax.matrix.json.GsonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("view") public class ViewConfig { - private Logger log = LoggerFactory.getLogger(ViewConfig.class); + private transient final Logger log = LoggerFactory.getLogger(ViewConfig.class); public static class Session { @@ -138,7 +134,7 @@ public class ViewConfig { @PostConstruct public void build() { log.info("--- View config ---"); - log.info("Session: {}", new Gson().toJson(session)); + log.info("Session: {}", GsonUtil.get().toJson(session)); } } diff --git a/src/main/java/io/kamax/mxisd/config/YamlConfigLoader.java b/src/main/java/io/kamax/mxisd/config/YamlConfigLoader.java new file mode 100644 index 0000000..70e4a09 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/config/YamlConfigLoader.java @@ -0,0 +1,42 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.config; + +import io.kamax.matrix.json.GsonUtil; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.representer.Representer; + +import java.io.FileInputStream; +import java.io.IOException; + +public class YamlConfigLoader { + + public static MxisdConfig loadFromFile(String path) throws IOException { + Representer rep = new Representer(); + rep.getPropertyUtils().setAllowReadOnlyProperties(true); + rep.getPropertyUtils().setSkipMissingProperties(true); + Yaml yaml = new Yaml(new Constructor(MxisdConfig.class), rep); + Object o = yaml.load(new FileInputStream(path)); + return GsonUtil.get().fromJson(GsonUtil.get().toJson(o), MxisdConfig.class); + } + +} diff --git a/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java b/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java index 04424cf..3522318 100644 --- a/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java @@ -259,7 +259,7 @@ public abstract class LdapConfig { } - private Logger log = LoggerFactory.getLogger(LdapConfig.class); + private transient final Logger log = LoggerFactory.getLogger(LdapConfig.class); private boolean enabled; private String filter; diff --git a/src/main/java/io/kamax/mxisd/config/ldap/generic/GenericLdapConfig.java b/src/main/java/io/kamax/mxisd/config/ldap/generic/GenericLdapConfig.java index 9274923..c6d8ff0 100644 --- a/src/main/java/io/kamax/mxisd/config/ldap/generic/GenericLdapConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ldap/generic/GenericLdapConfig.java @@ -21,13 +21,7 @@ package io.kamax.mxisd.config.ldap.generic; import io.kamax.mxisd.config.ldap.LdapConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -@Configuration -@ConfigurationProperties(prefix = "ldap") -@Primary public class GenericLdapConfig extends LdapConfig { @Override diff --git a/src/main/java/io/kamax/mxisd/config/ldap/netiq/NetIqLdapConfig.java b/src/main/java/io/kamax/mxisd/config/ldap/netiq/NetIqLdapConfig.java index e8fe617..8d85174 100644 --- a/src/main/java/io/kamax/mxisd/config/ldap/netiq/NetIqLdapConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ldap/netiq/NetIqLdapConfig.java @@ -21,11 +21,7 @@ package io.kamax.mxisd.config.ldap.netiq; import io.kamax.mxisd.config.ldap.LdapConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; -@Configuration -@ConfigurationProperties(prefix = "netiq") public class NetIqLdapConfig extends LdapConfig { @Override diff --git a/src/main/java/io/kamax/mxisd/config/memory/MemoryIdentityConfig.java b/src/main/java/io/kamax/mxisd/config/memory/MemoryIdentityConfig.java index 56cdfbe..5dc78e6 100644 --- a/src/main/java/io/kamax/mxisd/config/memory/MemoryIdentityConfig.java +++ b/src/main/java/io/kamax/mxisd/config/memory/MemoryIdentityConfig.java @@ -20,12 +20,9 @@ package io.kamax.mxisd.config.memory; -import org.springframework.stereotype.Component; - import java.util.ArrayList; import java.util.List; -@Component public class MemoryIdentityConfig { private String username; diff --git a/src/main/java/io/kamax/mxisd/config/memory/MemoryStoreConfig.java b/src/main/java/io/kamax/mxisd/config/memory/MemoryStoreConfig.java index 9e7000d..3e6f84e 100644 --- a/src/main/java/io/kamax/mxisd/config/memory/MemoryStoreConfig.java +++ b/src/main/java/io/kamax/mxisd/config/memory/MemoryStoreConfig.java @@ -20,17 +20,13 @@ package io.kamax.mxisd.config.memory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - +import java.util.ArrayList; import java.util.List; -@Configuration -@ConfigurationProperties("memory") public class MemoryStoreConfig { private boolean enabled; - private List identities; + private List identities = new ArrayList<>(); public boolean isEnabled() { return enabled; @@ -48,4 +44,8 @@ public class MemoryStoreConfig { this.identities = identities; } + public void build() { + // no-op + } + } diff --git a/src/main/java/io/kamax/mxisd/config/memory/MemoryThreePid.java b/src/main/java/io/kamax/mxisd/config/memory/MemoryThreePid.java index 2b397b9..3cd4922 100644 --- a/src/main/java/io/kamax/mxisd/config/memory/MemoryThreePid.java +++ b/src/main/java/io/kamax/mxisd/config/memory/MemoryThreePid.java @@ -21,9 +21,7 @@ package io.kamax.mxisd.config.memory; import io.kamax.matrix._ThreePid; -import org.springframework.stereotype.Component; -@Component public class MemoryThreePid implements _ThreePid { private String medium; diff --git a/src/main/java/io/kamax/mxisd/config/rest/RestBackendConfig.java b/src/main/java/io/kamax/mxisd/config/rest/RestBackendConfig.java index f9cce5e..f69e7b3 100644 --- a/src/main/java/io/kamax/mxisd/config/rest/RestBackendConfig.java +++ b/src/main/java/io/kamax/mxisd/config/rest/RestBackendConfig.java @@ -24,8 +24,6 @@ import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.net.MalformedURLException; @@ -33,8 +31,6 @@ import java.net.URL; import java.util.Objects; import java.util.Optional; -@Configuration -@ConfigurationProperties("rest") public class RestBackendConfig { public static class IdentityEndpoints { @@ -133,7 +129,7 @@ public class RestBackendConfig { } - private Logger log = LoggerFactory.getLogger(RestBackendConfig.class); + private transient final Logger log = LoggerFactory.getLogger(RestBackendConfig.class); private boolean enabled; private String host; diff --git a/src/main/java/io/kamax/mxisd/config/sql/SqlConfig.java b/src/main/java/io/kamax/mxisd/config/sql/SqlConfig.java index bd9d027..106876b 100644 --- a/src/main/java/io/kamax/mxisd/config/sql/SqlConfig.java +++ b/src/main/java/io/kamax/mxisd/config/sql/SqlConfig.java @@ -24,14 +24,13 @@ import io.kamax.mxisd.util.GsonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.Objects; public abstract class SqlConfig { - private transient Logger log = LoggerFactory.getLogger(SqlConfig.class); + private transient final Logger log = LoggerFactory.getLogger(SqlConfig.class); public static class Query { @@ -283,7 +282,6 @@ public abstract class SqlConfig { protected abstract String getProviderName(); - @PostConstruct public void build() { if (getAuth().isEnabled() == null) { getAuth().setEnabled(isEnabled()); diff --git a/src/main/java/io/kamax/mxisd/config/sql/generic/GenericSqlProviderConfig.java b/src/main/java/io/kamax/mxisd/config/sql/generic/GenericSqlProviderConfig.java index 8c69b81..ff6d3a3 100644 --- a/src/main/java/io/kamax/mxisd/config/sql/generic/GenericSqlProviderConfig.java +++ b/src/main/java/io/kamax/mxisd/config/sql/generic/GenericSqlProviderConfig.java @@ -21,13 +21,7 @@ package io.kamax.mxisd.config.sql.generic; import io.kamax.mxisd.config.sql.SqlConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -@Configuration -@ConfigurationProperties("sql") -@Primary public class GenericSqlProviderConfig extends SqlConfig { @Override diff --git a/src/main/java/io/kamax/mxisd/config/sql/synapse/SynapseSqlProviderConfig.java b/src/main/java/io/kamax/mxisd/config/sql/synapse/SynapseSqlProviderConfig.java index 9766ea2..c6f3281 100644 --- a/src/main/java/io/kamax/mxisd/config/sql/synapse/SynapseSqlProviderConfig.java +++ b/src/main/java/io/kamax/mxisd/config/sql/synapse/SynapseSqlProviderConfig.java @@ -23,13 +23,7 @@ package io.kamax.mxisd.config.sql.synapse; import io.kamax.mxisd.backend.sql.synapse.SynapseQueries; import io.kamax.mxisd.config.sql.SqlConfig; import org.apache.commons.lang.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import javax.annotation.PostConstruct; - -@Configuration -@ConfigurationProperties("synapseSql") public class SynapseSqlProviderConfig extends SqlConfig { @Override @@ -37,8 +31,9 @@ public class SynapseSqlProviderConfig extends SqlConfig { return "Synapse SQL"; } - @PostConstruct - public void doBuild() { + public void build() { + super.build(); + getAuth().setEnabled(false); // Synapse does the auth, we only act as a directory/identity service. // FIXME check that the DB is not the mxisd one diff --git a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java index a15c659..ce82d29 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java @@ -24,15 +24,11 @@ import io.kamax.mxisd.util.GsonUtil; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; -@Configuration -@ConfigurationProperties("notification.handlers.sendgrid") public class EmailSendGridConfig { public static class EmailTemplate { @@ -172,7 +168,7 @@ public class EmailSendGridConfig { } - private Logger log = LoggerFactory.getLogger(EmailSendGridConfig.class); + private transient final Logger log = LoggerFactory.getLogger(EmailSendGridConfig.class); private Api api = new Api(); private Identity identity = new Identity(); diff --git a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSmtpConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSmtpConfig.java index 7445042..332800b 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSmtpConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSmtpConfig.java @@ -23,16 +23,12 @@ package io.kamax.mxisd.config.threepid.connector; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties(prefix = "threepid.medium.email.connectors.smtp") public class EmailSmtpConfig { - private Logger log = LoggerFactory.getLogger(EmailSmtpConfig.class); + private transient final Logger log = LoggerFactory.getLogger(EmailSmtpConfig.class); private String host; private int port; diff --git a/src/main/java/io/kamax/mxisd/config/threepid/connector/PhoneTwilioConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/connector/PhoneTwilioConfig.java index c8977a3..f162a9f 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/connector/PhoneTwilioConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/connector/PhoneTwilioConfig.java @@ -22,18 +22,14 @@ package io.kamax.mxisd.config.threepid.connector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties(prefix = PhoneTwilioConfig.NAMESPACE) public class PhoneTwilioConfig { static final String NAMESPACE = "threepid.medium.msisdn.connectors.twilio"; - private Logger log = LoggerFactory.getLogger(PhoneTwilioConfig.class); + private transient final Logger log = LoggerFactory.getLogger(PhoneTwilioConfig.class); private String accountSid; private String authToken; diff --git a/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailConfig.java index 70a6b8b..e923f28 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailConfig.java @@ -26,18 +26,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.WordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("threepid.medium.email") public class EmailConfig { - private Logger log = LoggerFactory.getLogger(EmailConfig.class); - public static class Identity { private String from; private String name; @@ -60,13 +53,14 @@ public class EmailConfig { } + private transient final Logger log = LoggerFactory.getLogger(EmailConfig.class); + private String generator; private String connector; private MatrixConfig mxCfg; private Identity identity = new Identity(); - @Autowired public EmailConfig(MatrixConfig mxCfg) { this.mxCfg = mxCfg; } diff --git a/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailTemplateConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailTemplateConfig.java index a50e153..e91af08 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailTemplateConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/medium/EmailTemplateConfig.java @@ -22,16 +22,12 @@ package io.kamax.mxisd.config.threepid.medium; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("threepid.medium.email.generators.template") public class EmailTemplateConfig extends GenericTemplateConfig { - private static Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class); + private transient final Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class); @PostConstruct public void build() { diff --git a/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneConfig.java index ef1d9bb..dc6f1d4 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneConfig.java @@ -24,16 +24,12 @@ import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("threepid.medium.msisdn") public class PhoneConfig { - private Logger log = LoggerFactory.getLogger(PhoneConfig.class); + private transient final Logger log = LoggerFactory.getLogger(PhoneConfig.class); private String generator; private String connector; diff --git a/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneSmsTemplateConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneSmsTemplateConfig.java index 605da44..91b417c 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneSmsTemplateConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/medium/PhoneSmsTemplateConfig.java @@ -22,16 +22,12 @@ package io.kamax.mxisd.config.threepid.medium; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -@Configuration -@ConfigurationProperties("threepid.medium.msisdn.generators.template") public class PhoneSmsTemplateConfig extends GenericTemplateConfig { - private static Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class); + private transient final Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class); @PostConstruct public void build() { diff --git a/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java index 4e3d702..7684838 100644 --- a/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java +++ b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java @@ -20,22 +20,20 @@ package io.kamax.mxisd.config.threepid.notification; +import com.google.gson.JsonObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; -@Configuration -@ConfigurationProperties("notification") public class NotificationConfig { - private Logger log = LoggerFactory.getLogger(NotificationConfig.class); + private transient final Logger log = LoggerFactory.getLogger(NotificationConfig.class); private Map handler = new HashMap<>(); + private Map handlers = new HashMap<>(); public Map getHandler() { return handler; @@ -45,13 +43,19 @@ public class NotificationConfig { this.handler = handler; } + public Map getHandlers() { + return handlers; + } + + public void setHandlers(Map handlers) { + this.handlers = handlers; + } + @PostConstruct public void build() { log.info("--- Notification config ---"); log.info("Handlers:"); - handler.forEach((k, v) -> { - log.info("\t{}: {}", k, v); - }); + handler.forEach((k, v) -> log.info("\t{}: {}", k, v)); } } diff --git a/src/main/java/io/kamax/mxisd/config/wordpress/WordpressConfig.java b/src/main/java/io/kamax/mxisd/config/wordpress/WordpressConfig.java index 9ce3789..4776ba5 100644 --- a/src/main/java/io/kamax/mxisd/config/wordpress/WordpressConfig.java +++ b/src/main/java/io/kamax/mxisd/config/wordpress/WordpressConfig.java @@ -22,14 +22,10 @@ package io.kamax.mxisd.config.wordpress; import io.kamax.mxisd.exception.ConfigurationException; import org.apache.commons.lang.StringUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.Map; -@Configuration -@ConfigurationProperties("wordpress") public class WordpressConfig { public static class Credential { diff --git a/src/main/java/io/kamax/mxisd/controller/DefaultExceptionHandler.java b/src/main/java/io/kamax/mxisd/controller/DefaultExceptionHandler.java deleted file mode 100644 index b20a31d..0000000 --- a/src/main/java/io/kamax/mxisd/controller/DefaultExceptionHandler.java +++ /dev/null @@ -1,144 +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.controller; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; -import io.kamax.mxisd.exception.*; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.time.Instant; - -@ControllerAdvice -@ResponseBody -@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class DefaultExceptionHandler { - - private Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class); - - private static Gson gson = new Gson(); - - private String handle(HttpServletRequest req, String erroCode, String error) { - JsonObject obj = new JsonObject(); - obj.addProperty("errcode", erroCode); - obj.addProperty("error", error); - obj.addProperty("success", false); - log.info("Request {} {} - Error {}: {}", req.getMethod(), req.getRequestURL(), erroCode, error); - return gson.toJson(obj); - } - - @ExceptionHandler(RemoteLoginException.class) - public String handle(HttpServletRequest request, HttpServletResponse response, RemoteLoginException e) { - if (e.getErrorBodyMsgResp() != null) { - response.setStatus(e.getStatus()); - log.info("Request {} {} - Error {}: {}", request.getMethod(), request.getRequestURL(), e.getErrorCode(), e.getError()); - return gson.toJson(e.getErrorBodyMsgResp()); - } - return handleGeneric(request, response, e); - } - - @ExceptionHandler(InternalServerError.class) - public String handle(HttpServletRequest request, HttpServletResponse response, InternalServerError e) { - if (StringUtils.isNotBlank(e.getInternalReason())) { - log.error("Reference #{} - {}", e.getReference(), e.getInternalReason()); - } else { - log.error("Reference #{}", e); - } - - return handleGeneric(request, response, e); - } - - @ExceptionHandler(FeatureNotAvailable.class) - public String handle(HttpServletRequest request, HttpServletResponse response, FeatureNotAvailable e) { - if (StringUtils.isNotBlank(e.getInternalReason())) { - log.error("Feature not available: {}", e.getInternalReason()); - } - - return handleGeneric(request, response, e); - } - - @ExceptionHandler(HttpMatrixException.class) - public String handleGeneric(HttpServletRequest request, HttpServletResponse response, HttpMatrixException e) { - response.setStatus(e.getStatus()); - return handle(request, e.getErrorCode(), e.getError()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(MissingServletRequestParameterException.class) - public String handle(HttpServletRequest req, MissingServletRequestParameterException e) { - return handle(req, "M_INCOMPLETE_REQUEST", e.getMessage()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(InvalidResponseJsonException.class) - public String handle(HttpServletRequest req, InvalidResponseJsonException e) { - return handle(req, "M_INVALID_JSON", e.getMessage()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(JsonSyntaxException.class) - public String handle(HttpServletRequest req, JsonSyntaxException e) { - return handle(req, "M_INVALID_JSON", e.getMessage()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(JsonMemberNotFoundException.class) - public String handle(HttpServletRequest req, JsonMemberNotFoundException e) { - return handle(req, "M_JSON_MISSING_KEYS", e.getMessage()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(MappingAlreadyExistsException.class) - public String handle(HttpServletRequest req, MappingAlreadyExistsException e) { - return handle(req, "M_ALREADY_EXISTS", e.getMessage()); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(BadRequestException.class) - public String handle(HttpServletRequest req, BadRequestException e) { - return handle(req, "M_BAD_REQUEST", e.getMessage()); - } - - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - @ExceptionHandler(RuntimeException.class) - public String handle(HttpServletRequest req, RuntimeException e) { - log.error("Unknown error when handling {}", req.getRequestURL(), e); - return handle( - req, - "M_UNKNOWN", - StringUtils.defaultIfBlank( - e.getMessage(), - "An internal server error occurred. If this error persists, please contact support with reference #" + - Instant.now().toEpochMilli() - ) - ); - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/app/v1/AppServiceController.java b/src/main/java/io/kamax/mxisd/controller/app/v1/AppServiceController.java deleted file mode 100644 index 3db5c1f..0000000 --- a/src/main/java/io/kamax/mxisd/controller/app/v1/AppServiceController.java +++ /dev/null @@ -1,104 +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.controller.app.v1; - -import io.kamax.matrix.json.GsonUtil; -import io.kamax.mxisd.as.AppServiceHandler; -import io.kamax.mxisd.config.ListenerConfig; -import io.kamax.mxisd.exception.HttpMatrixException; -import io.kamax.mxisd.exception.NotAllowedException; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.concurrent.CompletableFuture; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; -import static org.springframework.web.bind.annotation.RequestMethod.PUT; - -@RestController -@CrossOrigin -@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -public class AppServiceController { - - private final Logger log = LoggerFactory.getLogger(AppServiceController.class); - private final ListenerConfig cfg; - - private final String notFoundBody; - private final AppServiceHandler handler; - - @Autowired - public AppServiceController(ListenerConfig cfg, AppServiceHandler handler) { - this.notFoundBody = GsonUtil.get().toJson(GsonUtil.makeObj("errcode", "io.kamax.mxisd.AS_NOT_FOUND")); - - this.cfg = cfg; - this.handler = handler; - } - - private void validateToken(String token) { - if (StringUtils.isBlank(token)) { - throw new HttpMatrixException(401, "M_UNAUTHORIZED", "No HS token"); - } - - if (!StringUtils.equals(cfg.getToken().getHs(), token)) { - throw new NotAllowedException("Invalid HS token"); - } - } - - @RequestMapping(value = "/rooms/**", method = GET) - public String getRoom(HttpServletResponse res, @RequestParam(name = "access_token", required = false) String token) { - validateToken(token); - - res.setStatus(404); - return notFoundBody; - } - - @RequestMapping(value = "/users/**", method = GET) - public String getUser(HttpServletResponse res, @RequestParam(name = "access_token", required = false) String token) { - validateToken(token); - - res.setStatus(404); - return notFoundBody; - } - - @RequestMapping(value = "/transactions/{txnId:.+}", method = PUT) - public CompletableFuture getTransaction( - HttpServletRequest request, - @RequestParam(name = "access_token", required = false) String token, - @PathVariable String txnId - ) { - validateToken(token); - - try { - log.info("Received AS transaction {}", txnId); - return handler.processTransaction(txnId, request.getInputStream()); - } catch (IOException e) { - throw new RuntimeException("AS Transaction " + txnId + ": I/O error when getting input", e); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/auth/v1/AuthController.java b/src/main/java/io/kamax/mxisd/controller/auth/v1/AuthController.java deleted file mode 100644 index f7fb7a9..0000000 --- a/src/main/java/io/kamax/mxisd/controller/auth/v1/AuthController.java +++ /dev/null @@ -1,124 +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.controller.auth.v1; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import io.kamax.mxisd.auth.AuthManager; -import io.kamax.mxisd.auth.UserAuthResult; -import io.kamax.mxisd.controller.auth.v1.io.CredentialsValidationResponse; -import io.kamax.mxisd.exception.JsonMemberNotFoundException; -import io.kamax.mxisd.util.GsonParser; -import io.kamax.mxisd.util.GsonUtil; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; - -@RestController -@CrossOrigin -@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -public class AuthController { - - // TODO export into SDK - private static final String logV1Url = "/_matrix/client/r0/login"; - - private Logger log = LoggerFactory.getLogger(AuthController.class); - - private Gson gson = GsonUtil.build(); - private GsonParser parser = new GsonParser(gson); - - @Autowired - private AuthManager mgr; - - @Autowired - private CloseableHttpClient client; - - @RequestMapping(value = "/_matrix-internal/identity/v1/check_credentials", method = RequestMethod.POST) - public String checkCredentials(HttpServletRequest req) { - try { - JsonObject authData = parser.parse(req.getInputStream(), "user"); - if (!authData.has("id") || !authData.has("password")) { - throw new JsonMemberNotFoundException("Missing id or password keys"); - } - - String id = authData.get("id").getAsString(); - log.info("Requested to check credentials for {}", id); - String password = authData.get("password").getAsString(); - - UserAuthResult result = mgr.authenticate(id, password); - CredentialsValidationResponse response = new CredentialsValidationResponse(result.isSuccess()); - - if (result.isSuccess()) { - response.setDisplayName(result.getDisplayName()); - response.getProfile().setThreePids(result.getThreePids()); - } - JsonElement authObj = gson.toJsonTree(response); - - JsonObject obj = new JsonObject(); - obj.add("auth", authObj); - obj.add("authentication", authObj); // TODO remove later, legacy support - return gson.toJson(obj); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @RequestMapping(value = logV1Url, method = RequestMethod.GET) - public String getLogin(HttpServletRequest req, HttpServletResponse res) { - URI target = URI.create(req.getRequestURL().toString()); - - try (CloseableHttpResponse hsResponse = client.execute(new HttpGet(mgr.resolveProxyUrl(target)))) { - res.setStatus(hsResponse.getStatusLine().getStatusCode()); - return EntityUtils.toString(hsResponse.getEntity()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @RequestMapping(value = logV1Url, method = RequestMethod.POST) - public String login(HttpServletRequest req) { - URI target = URI.create(req.getRequestURL().toString()); - try { - return mgr.proxyLogin(target, IOUtils.toString(req.getInputStream(), StandardCharsets.UTF_8)); - } catch (IOException e) { - log.error("Unable to read input data from client"); - throw new RuntimeException(e); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/directory/v1/UserDirectoryController.java b/src/main/java/io/kamax/mxisd/controller/directory/v1/UserDirectoryController.java deleted file mode 100644 index ae9d6c1..0000000 --- a/src/main/java/io/kamax/mxisd/controller/directory/v1/UserDirectoryController.java +++ /dev/null @@ -1,61 +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.controller.directory.v1; - -import com.google.gson.Gson; -import io.kamax.mxisd.controller.ProxyController; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; -import io.kamax.mxisd.directory.DirectoryManager; -import io.kamax.mxisd.util.GsonParser; -import io.kamax.mxisd.util.GsonUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.net.URI; - -@RestController -@CrossOrigin -@RequestMapping(path = "/_matrix/client/r0/user_directory", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class UserDirectoryController extends ProxyController { - - private Gson gson = GsonUtil.build(); - private GsonParser parser = new GsonParser(gson); - - @Autowired - private DirectoryManager mgr; - - @RequestMapping(path = "/search", method = RequestMethod.POST) - public String search(HttpServletRequest request) throws IOException { - String accessToken = getAccessToken(request); - UserDirectorySearchRequest searchQuery = parser.parse(request, UserDirectorySearchRequest.class); - URI target = URI.create(request.getRequestURL().toString()); - UserDirectorySearchResult result = mgr.search(target, accessToken, searchQuery.getSearchTerm()); - return gson.toJson(result); - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/InvitationController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/InvitationController.java deleted file mode 100644 index f364692..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/InvitationController.java +++ /dev/null @@ -1,82 +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.controller.identity.v1; - -import com.google.gson.Gson; -import io.kamax.matrix.MatrixID; -import io.kamax.matrix.crypto.KeyManager; -import io.kamax.mxisd.config.ServerConfig; -import io.kamax.mxisd.controller.identity.v1.io.ThreePidInviteReplyIO; -import io.kamax.mxisd.invitation.IThreePidInvite; -import io.kamax.mxisd.invitation.IThreePidInviteReply; -import io.kamax.mxisd.invitation.InvitationManager; -import io.kamax.mxisd.invitation.ThreePidInvite; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.Map; - -import static org.springframework.web.bind.annotation.RequestMethod.POST; - -@RestController -@CrossOrigin -@RequestMapping(path = IdentityAPIv1.BASE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -class InvitationController { - - private Logger log = LoggerFactory.getLogger(InvitationController.class); - - @Autowired - private InvitationManager mgr; - - @Autowired - private KeyManager keyMgr; - - @Autowired - private ServerConfig srvCfg; - - private Gson gson = new Gson(); - - @RequestMapping(value = "/store-invite", method = POST) - String store( - HttpServletRequest request, - @RequestParam String sender, - @RequestParam String medium, - @RequestParam String address, - @RequestParam("room_id") String roomId) { - Map parameters = new HashMap<>(); - for (String key : request.getParameterMap().keySet()) { - parameters.put(key, request.getParameter(key)); - } - IThreePidInvite invite = new ThreePidInvite(MatrixID.asAcceptable(sender), medium, address, roomId, parameters); - IThreePidInviteReply reply = mgr.storeInvite(invite); - - return gson.toJson(new ThreePidInviteReplyIO(reply, keyMgr.getPublicKeyBase64(keyMgr.getCurrentIndex()), srvCfg.getPublicUrl())); - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/KeyController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/KeyController.java deleted file mode 100644 index 2a2ff23..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/KeyController.java +++ /dev/null @@ -1,81 +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.controller.identity.v1; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import io.kamax.matrix.crypto.KeyManager; -import io.kamax.mxisd.controller.identity.v1.io.KeyValidityJson; -import io.kamax.mxisd.exception.BadRequestException; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; - -@RestController -@CrossOrigin -@RequestMapping(path = IdentityAPIv1.BASE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class KeyController { - - private Logger log = LoggerFactory.getLogger(KeyController.class); - - @Autowired - private KeyManager keyMgr; - - private Gson gson = new Gson(); - private String validKey = gson.toJson(new KeyValidityJson(true)); - private String invalidKey = gson.toJson(new KeyValidityJson(false)); - - @RequestMapping(value = "/pubkey/{keyType}:{keyId}", method = GET) - public String getKey(@PathVariable String keyType, @PathVariable int keyId) { - if (!"ed25519".contentEquals(keyType)) { - throw new BadRequestException("Invalid algorithm: " + keyType); - } - - log.info("Key {}:{} was requested", keyType, keyId); - JsonObject obj = new JsonObject(); - obj.addProperty("public_key", keyMgr.getPublicKeyBase64(keyId)); - return gson.toJson(obj); - } - - @RequestMapping(value = "/pubkey/ephemeral/isvalid", method = GET) - public String checkEphemeralKeyValidity(HttpServletRequest request) { - log.warn("Ephemeral key was requested but no ephemeral key are generated, replying not valid"); - - return invalidKey; - } - - @RequestMapping(value = "/pubkey/isvalid", method = GET) - public String checkKeyValidity(HttpServletRequest request, @RequestParam("public_key") String pubKey) { - log.info("Validating public key {}", pubKey); - - // TODO do in manager - boolean valid = StringUtils.equals(pubKey, keyMgr.getPublicKeyBase64(keyMgr.getCurrentIndex())); - return valid ? validKey : invalidKey; - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/MappingController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/MappingController.java deleted file mode 100644 index 51ade28..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/MappingController.java +++ /dev/null @@ -1,134 +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.controller.identity.v1; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import io.kamax.matrix.crypto.SignatureManager; -import io.kamax.matrix.event.EventKey; -import io.kamax.matrix.json.MatrixJson; -import io.kamax.mxisd.config.MatrixConfig; -import io.kamax.mxisd.controller.identity.v1.io.SingeLookupReplyJson; -import io.kamax.mxisd.exception.InternalServerError; -import io.kamax.mxisd.lookup.*; -import io.kamax.mxisd.lookup.strategy.LookupStrategy; -import io.kamax.mxisd.util.GsonParser; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; -import static org.springframework.web.bind.annotation.RequestMethod.POST; - -@RestController -@CrossOrigin -@RequestMapping(path = IdentityAPIv1.BASE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class MappingController { - - private Logger log = LoggerFactory.getLogger(MappingController.class); - private Gson gson = new Gson(); - private GsonParser parser = new GsonParser(gson); - - @Autowired - private MatrixConfig mxCfg; - - @Autowired - private LookupStrategy strategy; - - @Autowired - private SignatureManager signMgr; - - private void setRequesterInfo(ALookupRequest lookupReq, HttpServletRequest req) { - lookupReq.setRequester(req.getRemoteAddr()); - String xff = req.getHeader("X-FORWARDED-FOR"); - log.debug("XFF header: {}", xff); - lookupReq.setRecursive(StringUtils.isBlank(xff)); - if (!lookupReq.isRecursive()) { - lookupReq.setRecurseHosts(Arrays.asList(xff.split(","))); - lookupReq.setRequester(lookupReq.getRecurseHosts().get(lookupReq.getRecurseHosts().size() - 1)); - } - - lookupReq.setUserAgent(req.getHeader("USER-AGENT")); - } - - @RequestMapping(value = "/lookup", method = GET) - String lookup(HttpServletRequest request, @RequestParam String medium, @RequestParam String address) { - SingleLookupRequest lookupRequest = new SingleLookupRequest(); - setRequesterInfo(lookupRequest, request); - lookupRequest.setType(medium); - lookupRequest.setThreePid(address); - - log.info("Got single lookup request from {} with client {} - Is recursive? {}", lookupRequest.getRequester(), lookupRequest.getUserAgent(), lookupRequest.isRecursive()); - - Optional lookupOpt = strategy.find(lookupRequest); - if (!lookupOpt.isPresent()) { - log.info("No mapping was found, return empty JSON object"); - return "{}"; - } - - SingleLookupReply lookup = lookupOpt.get(); - - // FIXME signing should be done in the business model, not in the controller - JsonObject obj = gson.toJsonTree(new SingeLookupReplyJson(lookup)).getAsJsonObject(); - obj.add(EventKey.Signatures.get(), signMgr.signMessageGson(MatrixJson.encodeCanonical(obj))); - - return gson.toJson(obj); - } - - @RequestMapping(value = "/bulk_lookup", method = POST) - String bulkLookup(HttpServletRequest request) { - BulkLookupRequest lookupRequest = new BulkLookupRequest(); - setRequesterInfo(lookupRequest, request); - log.info("Got bulk lookup request from {} with client {} - Is recursive? {}", lookupRequest.getRequester(), lookupRequest.getUserAgent(), lookupRequest.isRecursive()); - - try { - ClientBulkLookupRequest input = parser.parse(request, ClientBulkLookupRequest.class); - List mappings = new ArrayList<>(); - for (List mappingRaw : input.getThreepids()) { - ThreePidMapping mapping = new ThreePidMapping(); - mapping.setMedium(mappingRaw.get(0)); - mapping.setValue(mappingRaw.get(1)); - mappings.add(mapping); - } - lookupRequest.setMappings(mappings); - - ClientBulkLookupAnswer answer = new ClientBulkLookupAnswer(); - answer.addAll(strategy.find(lookupRequest)); - return gson.toJson(answer); - } catch (IOException e) { - throw new InternalServerError(e); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionController.java deleted file mode 100644 index 6f638c3..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionController.java +++ /dev/null @@ -1,92 +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.controller.identity.v1; - -import io.kamax.mxisd.config.ServerConfig; -import io.kamax.mxisd.config.ViewConfig; -import io.kamax.mxisd.controller.identity.v1.remote.RemoteIdentityAPIv1; -import io.kamax.mxisd.session.SessionMananger; -import io.kamax.mxisd.session.ValidationResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.MalformedURLException; -import java.net.URL; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; - -@Controller -@RequestMapping(path = IdentityAPIv1.BASE) -class SessionController { - - private Logger log = LoggerFactory.getLogger(SessionController.class); - - @Autowired - private ServerConfig srvCfg; - - @Autowired - private SessionMananger mgr; - - @Autowired - private ViewConfig viewCfg; - - @RequestMapping(value = "/validate/{medium}/submitToken", method = GET) - public String validate( - HttpServletRequest request, - HttpServletResponse response, - @RequestParam String sid, - @RequestParam("client_secret") String secret, - @RequestParam String token, - Model model - ) { - log.info("Requested: {}?{}", request.getRequestURL(), request.getQueryString()); - - ValidationResult r = mgr.validate(sid, secret, token); - log.info("Session {} was validated", sid); - if (r.getNextUrl().isPresent()) { - String url = r.getNextUrl().get(); - try { - url = new URL(url).toString(); - } catch (MalformedURLException e) { - log.info("Session next URL {} is not a valid one, will prepend public URL {}", url, srvCfg.getPublicUrl()); - url = srvCfg.getPublicUrl() + r.getNextUrl().get(); - } - log.info("Session {} validation: next URL is present, redirecting to {}", sid, url); - return "redirect:" + url; - } else { - if (r.isCanRemote()) { - String url = srvCfg.getPublicUrl() + RemoteIdentityAPIv1.getRequestToken(r.getSession().getId(), r.getSession().getSecret()); - model.addAttribute("remoteSessionLink", url); - return viewCfg.getSession().getLocalRemote().getOnTokenSubmit().getSuccess(); - } else { - return viewCfg.getSession().getLocal().getOnTokenSubmit().getSuccess(); - } - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionRestController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionRestController.java deleted file mode 100644 index e5b8c03..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/SessionRestController.java +++ /dev/null @@ -1,188 +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.controller.identity.v1; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import io.kamax.matrix.ThreePid; -import io.kamax.matrix.ThreePidMedium; -import io.kamax.mxisd.config.ServerConfig; -import io.kamax.mxisd.config.ViewConfig; -import io.kamax.mxisd.controller.identity.v1.io.SessionEmailTokenRequestJson; -import io.kamax.mxisd.controller.identity.v1.io.SessionPhoneTokenRequestJson; -import io.kamax.mxisd.controller.identity.v1.io.SuccessStatusJson; -import io.kamax.mxisd.exception.BadRequestException; -import io.kamax.mxisd.exception.SessionNotValidatedException; -import io.kamax.mxisd.invitation.InvitationManager; -import io.kamax.mxisd.lookup.ThreePidValidation; -import io.kamax.mxisd.session.SessionMananger; -import io.kamax.mxisd.session.ValidationResult; -import io.kamax.mxisd.util.GsonParser; -import org.apache.http.HttpStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -import static org.springframework.web.bind.annotation.RequestMethod.POST; - -@RestController -@CrossOrigin -@RequestMapping(path = IdentityAPIv1.BASE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class SessionRestController { - - private Logger log = LoggerFactory.getLogger(SessionRestController.class); - - private class Sid { // FIXME replace with RequestTokenResponse - - private String sid; - - public Sid(String sid) { - setSid(sid); - } - - String getSid() { - return sid; - } - - void setSid(String sid) { - this.sid = sid; - } - } - - @Autowired - private ServerConfig srvCfg; - - @Autowired - private SessionMananger mgr; - - @Autowired - private InvitationManager invMgr; - - @Autowired - private ViewConfig viewCfg; - - private Gson gson = new Gson(); - private GsonParser parser = new GsonParser(gson); - - @RequestMapping(value = "/validate/{medium}/requestToken") - String init(HttpServletRequest request, HttpServletResponse response, @PathVariable String medium) throws IOException { - log.info("Request {}: {}", request.getMethod(), request.getRequestURL(), request.getQueryString()); - if (ThreePidMedium.Email.is(medium)) { - SessionEmailTokenRequestJson req = parser.parse(request, SessionEmailTokenRequestJson.class); - return gson.toJson(new Sid(mgr.create( - request.getRemoteHost(), - new ThreePid(req.getMedium(), req.getValue()), - req.getSecret(), - req.getAttempt(), - req.getNextLink()))); - } - - if (ThreePidMedium.PhoneNumber.is(medium)) { - SessionPhoneTokenRequestJson req = parser.parse(request, SessionPhoneTokenRequestJson.class); - ThreePid threepid = new ThreePid(req.getMedium(), req.getValue()); - - String sessionId = mgr.create( - request.getRemoteHost(), - threepid, - req.getSecret(), - req.getAttempt(), - req.getNextLink()); - - JsonObject res = new JsonObject(); - res.addProperty("sid", sessionId); - res.addProperty(threepid.getMedium(), threepid.getAddress()); - return gson.toJson(res); - } - - JsonObject obj = new JsonObject(); - obj.addProperty("errcode", "M_INVALID_3PID_TYPE"); - obj.addProperty("error", medium + " is not supported as a 3PID type"); - response.setStatus(HttpStatus.SC_BAD_REQUEST); - return gson.toJson(obj); - } - - @RequestMapping(value = "/validate/{medium}/submitToken", method = POST) - public String validate( - HttpServletRequest request, - HttpServletResponse response, - @RequestParam String sid, - @RequestParam("client_secret") String secret, - @RequestParam String token, - Model model - ) { - log.info("Requested: {}", request.getRequestURL()); - - ValidationResult r = mgr.validate(sid, secret, token); - log.info("Session {} was validated", sid); - - return gson.toJson(new SuccessStatusJson(true)); - } - - @RequestMapping(value = "/3pid/getValidated3pid") - String check(HttpServletRequest request, HttpServletResponse response, - @RequestParam String sid, @RequestParam("client_secret") String secret) { - log.info("Requested: {}", request.getRequestURL(), request.getQueryString()); - - try { - ThreePidValidation pid = mgr.getValidated(sid, secret); - - JsonObject obj = new JsonObject(); - obj.addProperty("medium", pid.getMedium()); - obj.addProperty("address", pid.getAddress()); - obj.addProperty("validated_at", pid.getValidation().toEpochMilli()); - - return gson.toJson(obj); - } catch (SessionNotValidatedException e) { - log.info("Session {} was requested but has not yet been validated", sid); - throw e; - } - } - - @RequestMapping(value = "/3pid/bind") - String bind(HttpServletRequest request, HttpServletResponse response, - @RequestParam String sid, @RequestParam("client_secret") String secret, @RequestParam String mxid) { - log.info("Requested: {}", request.getRequestURL(), request.getQueryString()); - try { - mgr.bind(sid, secret, mxid); - return "{}"; - } catch (BadRequestException e) { - log.info("requested session was not validated"); - - JsonObject obj = new JsonObject(); - obj.addProperty("errcode", "M_SESSION_NOT_VALIDATED"); - obj.addProperty("error", e.getMessage()); - response.setStatus(HttpStatus.SC_BAD_REQUEST); - return gson.toJson(obj); - } finally { - // If a user registers, there is no standard login event. Instead, this is the only way to trigger - // resolution at an appropriate time. Meh at synapse/Riot! - invMgr.lookupMappingsForInvites(); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteSessionController.java b/src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteSessionController.java deleted file mode 100644 index 4c17c59..0000000 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteSessionController.java +++ /dev/null @@ -1,59 +0,0 @@ -package io.kamax.mxisd.controller.identity.v1.remote; - -import io.kamax.mxisd.config.ViewConfig; -import io.kamax.mxisd.exception.SessionNotValidatedException; -import io.kamax.mxisd.session.SessionMananger; -import io.kamax.mxisd.threepid.session.IThreePidSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - -import javax.servlet.http.HttpServletRequest; - -import static io.kamax.mxisd.controller.identity.v1.remote.RemoteIdentityAPIv1.SESSION_CHECK; -import static io.kamax.mxisd.controller.identity.v1.remote.RemoteIdentityAPIv1.SESSION_REQUEST_TOKEN; - -@Controller -public class RemoteSessionController { - - private Logger log = LoggerFactory.getLogger(RemoteSessionController.class); - - @Autowired - private ViewConfig viewCfg; - - @Autowired - private SessionMananger mgr; - - @RequestMapping(path = SESSION_REQUEST_TOKEN) - public String requestToken( - HttpServletRequest request, - @RequestParam String sid, - @RequestParam("client_secret") String secret, - Model model - ) { - log.info("Request {}: {}", request.getMethod(), request.getRequestURL()); - IThreePidSession session = mgr.createRemote(sid, secret); - model.addAttribute("checkLink", RemoteIdentityAPIv1.getSessionCheck(session.getId(), session.getSecret())); - return viewCfg.getSession().getRemote().getOnRequest().getSuccess(); - } - - @RequestMapping(path = SESSION_CHECK) - public String check( - HttpServletRequest request, - @RequestParam String sid, - @RequestParam("client_secret") String secret) { - log.info("Request {}: {}", request.getMethod(), request.getRequestURL()); - - try { - mgr.validateRemote(sid, secret); - return viewCfg.getSession().getRemote().getOnCheck().getSuccess(); - } catch (SessionNotValidatedException e) { - return viewCfg.getSession().getRemote().getOnCheck().getFailure(); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileController.java b/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileController.java deleted file mode 100644 index 775fae2..0000000 --- a/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileController.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * mxisd - Matrix Identity Server Daemon - * Copyright (C) 2018 Kamax Sàrl - * - * 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.controller.profile.v1; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import io.kamax.matrix.MatrixID; -import io.kamax.matrix._ThreePid; -import io.kamax.mxisd.controller.ProxyController; -import io.kamax.mxisd.dns.ClientDnsOverwrite; -import io.kamax.mxisd.profile.ProfileManager; -import io.kamax.mxisd.util.GsonUtil; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URI; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -@RestController -@CrossOrigin -@RequestMapping(path = "/_matrix/client/r0/profile", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class ProfileController extends ProxyController { - - private final Logger log = LoggerFactory.getLogger(ProfileController.class); - private final ProfileManager mgr; - private final CloseableHttpClient client; - private final ClientDnsOverwrite dns; - private final JsonParser parser; - private final Gson gson; - - @Autowired - public ProfileController(ProfileManager mgr, CloseableHttpClient client, ClientDnsOverwrite dns) { - this.mgr = mgr; - this.client = client; - this.dns = dns; - this.parser = new JsonParser(); - this.gson = GsonUtil.build(); - } - - // FIXME do properly in the SDK (headers, check access token, etc.) - private String resolveProxyUrl(HttpServletRequest req) { - URI target = URI.create(req.getRequestURL().toString() + (Objects.isNull(req.getQueryString()) ? "" : "?" + req.getQueryString())); - URIBuilder builder = dns.transform(target); - String urlToLogin = builder.toString(); - log.info("Proxy resolution: {} to {}", target.toString(), urlToLogin); - return urlToLogin; - } - - @RequestMapping("/{userId:.+}") - public String getProfile(HttpServletRequest req, HttpServletResponse res, @PathVariable String userId) { - Optional accessTokenOpt = findAccessToken(req); - HttpGet reqOut = new HttpGet(resolveProxyUrl(req)); - accessTokenOpt.ifPresent(accessToken -> reqOut.addHeader("Authorization", "Bearer " + accessToken)); - - try (CloseableHttpResponse hsResponse = client.execute(reqOut)) { - res.setStatus(hsResponse.getStatusLine().getStatusCode()); - JsonElement el = parser.parse(EntityUtils.toString(hsResponse.getEntity())); - List<_ThreePid> list = mgr.getThreepids(MatrixID.asAcceptable(userId)); - if (!list.isEmpty() && el.isJsonObject()) { - JsonObject obj = el.getAsJsonObject(); - obj.add("threepids", GsonUtil.build().toJsonTree(list)); - } - return gson.toJson(el); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileInternalController.java b/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileInternalController.java deleted file mode 100644 index 0f206ad..0000000 --- a/src/main/java/io/kamax/mxisd/controller/profile/v1/ProfileInternalController.java +++ /dev/null @@ -1,58 +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.controller.profile.v1; - -import io.kamax.matrix.MatrixID; -import io.kamax.matrix._MatrixID; -import io.kamax.matrix.json.GsonUtil; -import io.kamax.mxisd.profile.ProfileManager; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; - -@RestController -@CrossOrigin -@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class ProfileInternalController { - - private final ProfileManager mgr; - - public ProfileInternalController(ProfileManager mgr) { - this.mgr = mgr; - } - - @RequestMapping(method = GET, path = "/_matrix-internal/profile/v1/{userId:.+}") - public String getProfile(@PathVariable String userId) throws UnsupportedEncodingException { - userId = URLDecoder.decode(userId, StandardCharsets.UTF_8.name()); - _MatrixID mxId = MatrixID.asAcceptable(userId); - - return GsonUtil.get().toJson(GsonUtil.makeObj("roles", GsonUtil.asArray(mgr.getRoles(mxId)))); - } - -} diff --git a/src/main/java/io/kamax/mxisd/directory/DirectoryManager.java b/src/main/java/io/kamax/mxisd/directory/DirectoryManager.java index 0b9b00d..872b5bc 100644 --- a/src/main/java/io/kamax/mxisd/directory/DirectoryManager.java +++ b/src/main/java/io/kamax/mxisd/directory/DirectoryManager.java @@ -20,16 +20,15 @@ package io.kamax.mxisd.directory; -import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import io.kamax.matrix.MatrixErrorInfo; +import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.config.DirectoryConfig; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.dns.ClientDnsOverwrite; import io.kamax.mxisd.exception.HttpMatrixException; import io.kamax.mxisd.exception.InternalServerError; -import io.kamax.mxisd.util.GsonUtil; +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; @@ -40,8 +39,6 @@ import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.net.URI; @@ -49,25 +46,19 @@ import java.nio.charset.Charset; import java.util.List; import java.util.stream.Collectors; -@Component public class DirectoryManager { - private Logger log = LoggerFactory.getLogger(DirectoryManager.class); + private transient final Logger log = LoggerFactory.getLogger(DirectoryManager.class); private DirectoryConfig cfg; + private ClientDnsOverwrite dns; + private CloseableHttpClient client; private List providers; - private ClientDnsOverwrite dns; - private Gson gson; - - @Autowired - private CloseableHttpClient client; - - @Autowired - public DirectoryManager(DirectoryConfig cfg, List providers, ClientDnsOverwrite dns) { + public DirectoryManager(DirectoryConfig cfg, ClientDnsOverwrite dns, CloseableHttpClient client, List providers) { this.cfg = cfg; this.dns = dns; - this.gson = GsonUtil.build(); + this.client = client; this.providers = providers.stream().filter(IDirectoryProvider::isEnabled).collect(Collectors.toList()); log.info("Directory providers:"); @@ -98,7 +89,7 @@ public class DirectoryManager { String body = IOUtils.toString(res.getEntity().getContent(), charset); if (status != 200) { - MatrixErrorInfo info = gson.fromJson(body, MatrixErrorInfo.class); + MatrixErrorInfo info = GsonUtil.get().fromJson(body, MatrixErrorInfo.class); if (StringUtils.equals("M_UNRECOGNIZED", info.getErrcode())) { // FIXME no hardcoding, use Enum log.warn("Homeserver does not support Directory feature, skipping"); } else { @@ -107,7 +98,7 @@ public class DirectoryManager { } } - UserDirectorySearchResult resultHs = gson.fromJson(body, UserDirectorySearchResult.class); + UserDirectorySearchResult resultHs = GsonUtil.get().fromJson(body, UserDirectorySearchResult.class); log.info("Found {} match(es) in HS for '{}'", resultHs.getResults().size(), query); result.getResults().addAll(resultHs.getResults()); if (resultHs.isLimited()) { diff --git a/src/main/java/io/kamax/mxisd/spring/CloseableHttpClientFactory.java b/src/main/java/io/kamax/mxisd/directory/DirectoryProviders.java similarity index 58% rename from src/main/java/io/kamax/mxisd/spring/CloseableHttpClientFactory.java rename to src/main/java/io/kamax/mxisd/directory/DirectoryProviders.java index 9f352ad..9f45109 100644 --- a/src/main/java/io/kamax/mxisd/spring/CloseableHttpClientFactory.java +++ b/src/main/java/io/kamax/mxisd/directory/DirectoryProviders.java @@ -18,23 +18,23 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.spring; +package io.kamax.mxisd.directory; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; -@Configuration -public class CloseableHttpClientFactory { +public class DirectoryProviders { - @Bean - public CloseableHttpClient getClient() { - return HttpClients.custom() - .setUserAgent("mxisd") - .setMaxConnPerRoute(Integer.MAX_VALUE) - .setMaxConnTotal(Integer.MAX_VALUE) - .build(); + private static final List> suppliers = new ArrayList<>(); + + public static void register(Supplier supplier) { + suppliers.add(supplier); + } + + public static List get() { + return suppliers.stream().map(Supplier::get).collect(Collectors.toList()); } } diff --git a/src/main/java/io/kamax/mxisd/directory/IDirectoryProvider.java b/src/main/java/io/kamax/mxisd/directory/IDirectoryProvider.java index 1069ed0..c947009 100644 --- a/src/main/java/io/kamax/mxisd/directory/IDirectoryProvider.java +++ b/src/main/java/io/kamax/mxisd/directory/IDirectoryProvider.java @@ -20,7 +20,7 @@ package io.kamax.mxisd.directory; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; public interface IDirectoryProvider { diff --git a/src/main/java/io/kamax/mxisd/dns/ClientDnsOverwrite.java b/src/main/java/io/kamax/mxisd/dns/ClientDnsOverwrite.java index 5f17116..5895ff4 100644 --- a/src/main/java/io/kamax/mxisd/dns/ClientDnsOverwrite.java +++ b/src/main/java/io/kamax/mxisd/dns/ClientDnsOverwrite.java @@ -26,8 +26,6 @@ import io.kamax.mxisd.exception.InternalServerError; import org.apache.http.client.utils.URIBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.MalformedURLException; import java.net.URI; @@ -37,14 +35,12 @@ import java.util.Map; import static io.kamax.mxisd.config.DnsOverwriteConfig.Entry; -@Component public class ClientDnsOverwrite { - private Logger log = LoggerFactory.getLogger(ClientDnsOverwrite.class); + private transient final Logger log = LoggerFactory.getLogger(ClientDnsOverwrite.class); private Map mappings; - @Autowired public ClientDnsOverwrite(DnsOverwriteConfig cfg) { mappings = new HashMap<>(); cfg.getHomeserver().getClient().forEach(e -> mappings.put(e.getName(), e)); diff --git a/src/main/java/io/kamax/mxisd/dns/FederationDnsOverwrite.java b/src/main/java/io/kamax/mxisd/dns/FederationDnsOverwrite.java index 7f8ebb3..01abf0b 100644 --- a/src/main/java/io/kamax/mxisd/dns/FederationDnsOverwrite.java +++ b/src/main/java/io/kamax/mxisd/dns/FederationDnsOverwrite.java @@ -21,11 +21,8 @@ package io.kamax.mxisd.dns; import io.kamax.mxisd.config.DnsOverwriteConfig; -import io.kamax.mxisd.config.ServerConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @@ -33,17 +30,13 @@ import java.util.Optional; import static io.kamax.mxisd.config.DnsOverwriteConfig.Entry; -@Component public class FederationDnsOverwrite { - private Logger log = LoggerFactory.getLogger(FederationDnsOverwrite.class); + private transient final Logger log = LoggerFactory.getLogger(FederationDnsOverwrite.class); - private ServerConfig srvCfg; private Map mappings; - @Autowired - public FederationDnsOverwrite(DnsOverwriteConfig cfg, ServerConfig srvCfg) { - this.srvCfg = srvCfg; + public FederationDnsOverwrite(DnsOverwriteConfig cfg) { mappings = new HashMap<>(); cfg.getHomeserver().getFederation().forEach(e -> mappings.put(e.getName(), e)); diff --git a/src/main/java/io/kamax/mxisd/exception/BadRequestException.java b/src/main/java/io/kamax/mxisd/exception/BadRequestException.java index d19819e..051ce56 100644 --- a/src/main/java/io/kamax/mxisd/exception/BadRequestException.java +++ b/src/main/java/io/kamax/mxisd/exception/BadRequestException.java @@ -20,10 +20,6 @@ package io.kamax.mxisd.exception; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.BAD_REQUEST) public class BadRequestException extends RuntimeException { public BadRequestException(String s) { diff --git a/src/main/java/io/kamax/mxisd/exception/ConfigurationException.java b/src/main/java/io/kamax/mxisd/exception/ConfigurationException.java index f303357..02c6051 100644 --- a/src/main/java/io/kamax/mxisd/exception/ConfigurationException.java +++ b/src/main/java/io/kamax/mxisd/exception/ConfigurationException.java @@ -28,7 +28,7 @@ public class ConfigurationException extends RuntimeException { private String detailedMsg; public ConfigurationException(String key) { - super("Invalid or empty value for configuration key " + key); + super("Invalid or empty value for configuration item " + key); } public ConfigurationException(Throwable t) { diff --git a/src/main/java/io/kamax/mxisd/exception/InvalidCredentialsException.java b/src/main/java/io/kamax/mxisd/exception/InvalidCredentialsException.java index 192dc5b..23c00fb 100644 --- a/src/main/java/io/kamax/mxisd/exception/InvalidCredentialsException.java +++ b/src/main/java/io/kamax/mxisd/exception/InvalidCredentialsException.java @@ -20,10 +20,6 @@ package io.kamax.mxisd.exception; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.FORBIDDEN) public class InvalidCredentialsException extends RuntimeException { public InvalidCredentialsException() { diff --git a/src/main/java/io/kamax/mxisd/MatrixIdentityServerApplication.java b/src/main/java/io/kamax/mxisd/exception/NotFoundException.java similarity index 67% rename from src/main/java/io/kamax/mxisd/MatrixIdentityServerApplication.java rename to src/main/java/io/kamax/mxisd/exception/NotFoundException.java index ff1acac..b076325 100644 --- a/src/main/java/io/kamax/mxisd/MatrixIdentityServerApplication.java +++ b/src/main/java/io/kamax/mxisd/exception/NotFoundException.java @@ -1,6 +1,6 @@ /* * mxisd - Matrix Identity Server Daemon - * Copyright (C) 2017 Kamax Sarl + * Copyright (C) 2018 Kamax Sarl * * https://www.kamax.io/ * @@ -18,16 +18,13 @@ * along with this program. If not, see . */ -package io.kamax.mxisd; +package io.kamax.mxisd.exception; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; +// FIXME duplicate of ObjectNotFoundException - see if we can merge +public class NotFoundException extends HttpMatrixException { -@SpringBootApplication -public class MatrixIdentityServerApplication { - - public static void main(String[] args) { - SpringApplication.run(MatrixIdentityServerApplication.class, args); + public NotFoundException() { + super(404, "M_NOT_FOUND", "Not found"); } } diff --git a/src/main/java/io/kamax/mxisd/exception/NotImplementedException.java b/src/main/java/io/kamax/mxisd/exception/NotImplementedException.java index 7668889..f666c34 100644 --- a/src/main/java/io/kamax/mxisd/exception/NotImplementedException.java +++ b/src/main/java/io/kamax/mxisd/exception/NotImplementedException.java @@ -20,10 +20,6 @@ package io.kamax.mxisd.exception; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.NOT_IMPLEMENTED) public class NotImplementedException extends RuntimeException { public NotImplementedException(String s) { diff --git a/src/main/java/io/kamax/mxisd/exception/ObjectNotFoundException.java b/src/main/java/io/kamax/mxisd/exception/ObjectNotFoundException.java index cb4cc30..81f79f0 100644 --- a/src/main/java/io/kamax/mxisd/exception/ObjectNotFoundException.java +++ b/src/main/java/io/kamax/mxisd/exception/ObjectNotFoundException.java @@ -20,10 +20,6 @@ package io.kamax.mxisd.exception; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.NOT_FOUND) public class ObjectNotFoundException extends RuntimeException { public ObjectNotFoundException(String type, String id) { diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/IdentityAPIv1.java b/src/main/java/io/kamax/mxisd/http/IsAPIv1.java similarity index 82% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/IdentityAPIv1.java rename to src/main/java/io/kamax/mxisd/http/IsAPIv1.java index bdcc31b..bd070f2 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/IdentityAPIv1.java +++ b/src/main/java/io/kamax/mxisd/http/IsAPIv1.java @@ -18,15 +18,15 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1; +package io.kamax.mxisd.http; -public class IdentityAPIv1 { +public class IsAPIv1 { - public static final String BASE = "/_matrix/identity/api/v1"; + public static final String Base = "/_matrix/identity/api/v1"; public static String getValidate(String medium, String sid, String secret, String token) { // FIXME use some kind of URLBuilder - return BASE + "/validate/" + medium + "/submitToken?sid=" + sid + "&client_secret=" + secret + "&token=" + token; + return Base + "/validate/" + medium + "/submitToken?sid=" + sid + "&client_secret=" + secret + "&token=" + token; } } diff --git a/src/main/java/io/kamax/mxisd/controller/auth/v1/io/CredentialsValidationResponse.java b/src/main/java/io/kamax/mxisd/http/io/CredentialsValidationResponse.java similarity index 97% rename from src/main/java/io/kamax/mxisd/controller/auth/v1/io/CredentialsValidationResponse.java rename to src/main/java/io/kamax/mxisd/http/io/CredentialsValidationResponse.java index 3950dbe..1adbb61 100644 --- a/src/main/java/io/kamax/mxisd/controller/auth/v1/io/CredentialsValidationResponse.java +++ b/src/main/java/io/kamax/mxisd/http/io/CredentialsValidationResponse.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.auth.v1.io; +package io.kamax.mxisd.http.io; import io.kamax.matrix.ThreePid; diff --git a/src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchRequest.java b/src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchRequest.java similarity index 96% rename from src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchRequest.java rename to src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchRequest.java index 8044678..2d11ecb 100644 --- a/src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchRequest.java +++ b/src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchRequest.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.directory.v1.io; +package io.kamax.mxisd.http.io; public class UserDirectorySearchRequest { diff --git a/src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchResult.java b/src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchResult.java similarity index 98% rename from src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchResult.java rename to src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchResult.java index dfc2da7..ed2b347 100644 --- a/src/main/java/io/kamax/mxisd/controller/directory/v1/io/UserDirectorySearchResult.java +++ b/src/main/java/io/kamax/mxisd/http/io/UserDirectorySearchResult.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.directory.v1.io; +package io.kamax.mxisd.http.io; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupAnswer.java b/src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupAnswer.java similarity index 96% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupAnswer.java rename to src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupAnswer.java index d01ab0e..71db985 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupAnswer.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupAnswer.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1; +package io.kamax.mxisd.http.io.identity; import io.kamax.mxisd.lookup.ThreePidMapping; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupRequest.java b/src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupRequest.java similarity index 96% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupRequest.java rename to src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupRequest.java index b0e0fb6..dfa4f54 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/ClientBulkLookupRequest.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/ClientBulkLookupRequest.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1; +package io.kamax.mxisd.http.io.identity; import io.kamax.mxisd.lookup.ThreePidMapping; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/GenericTokenRequestJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/GenericTokenRequestJson.java similarity index 95% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/GenericTokenRequestJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/GenericTokenRequestJson.java index 5d2095e..9448ed6 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/GenericTokenRequestJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/GenericTokenRequestJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; public abstract class GenericTokenRequestJson { diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/KeyValidityJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/KeyValidityJson.java similarity index 95% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/KeyValidityJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/KeyValidityJson.java index 023528e..e3e2bbd 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/KeyValidityJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/KeyValidityJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; public class KeyValidityJson { diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/RequestTokenResponse.java b/src/main/java/io/kamax/mxisd/http/io/identity/RequestTokenResponse.java similarity index 82% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/RequestTokenResponse.java rename to src/main/java/io/kamax/mxisd/http/io/identity/RequestTokenResponse.java index 8a35bdd..9796c71 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/RequestTokenResponse.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/RequestTokenResponse.java @@ -18,12 +18,20 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; public class RequestTokenResponse { private String sid; + public RequestTokenResponse() { + // for (de)serializers + } + + public RequestTokenResponse(String sid) { + this.sid = sid; + } + public String getSid() { return sid; } diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionEmailTokenRequestJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/SessionEmailTokenRequestJson.java similarity index 95% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionEmailTokenRequestJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/SessionEmailTokenRequestJson.java index a7290e0..814d6a8 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionEmailTokenRequestJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/SessionEmailTokenRequestJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; import io.kamax.matrix.ThreePidMedium; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionPhoneTokenRequestJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/SessionPhoneTokenRequestJson.java similarity index 96% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionPhoneTokenRequestJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/SessionPhoneTokenRequestJson.java index c42df71..c993cc1 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SessionPhoneTokenRequestJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/SessionPhoneTokenRequestJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SingeLookupReplyJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/SingeLookupReplyJson.java similarity index 97% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/SingeLookupReplyJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/SingeLookupReplyJson.java index 3a42c1f..32c1d91 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SingeLookupReplyJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/SingeLookupReplyJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; import io.kamax.mxisd.lookup.SingleLookupReply; diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SuccessStatusJson.java b/src/main/java/io/kamax/mxisd/http/io/identity/SuccessStatusJson.java similarity index 95% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/SuccessStatusJson.java rename to src/main/java/io/kamax/mxisd/http/io/identity/SuccessStatusJson.java index 1d02570..cd69009 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/SuccessStatusJson.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/SuccessStatusJson.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; public class SuccessStatusJson { diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/ThreePidInviteReplyIO.java b/src/main/java/io/kamax/mxisd/http/io/identity/ThreePidInviteReplyIO.java similarity index 97% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/io/ThreePidInviteReplyIO.java rename to src/main/java/io/kamax/mxisd/http/io/identity/ThreePidInviteReplyIO.java index ba3cf45..5fdb9ed 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/io/ThreePidInviteReplyIO.java +++ b/src/main/java/io/kamax/mxisd/http/io/identity/ThreePidInviteReplyIO.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.io; +package io.kamax.mxisd.http.io.identity; import io.kamax.mxisd.invitation.IThreePidInviteReply; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/BasicHttpHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/BasicHttpHandler.java new file mode 100644 index 0000000..884c0c4 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/BasicHttpHandler.java @@ -0,0 +1,129 @@ +/* + * 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; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.exception.HttpMatrixException; +import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.proxy.Response; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.util.HttpString; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; + +public abstract class BasicHttpHandler implements HttpHandler { + + private transient final Logger log = LoggerFactory.getLogger(BasicHttpHandler.class); + + protected String getRemoteHostAddress(HttpServerExchange exchange) { + return ((InetSocketAddress) exchange.getConnection().getPeerAddress()).getAddress().getHostAddress(); + } + + protected String getQueryParameter(HttpServerExchange exchange, String name) { + try { + String raw = exchange.getQueryParameters().getOrDefault(name, new LinkedList<>()).peekFirst(); + return URLDecoder.decode(raw, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new InternalServerError(e); + } + } + + protected String getPathVariable(HttpServerExchange exchange, String name) { + return getQueryParameter(exchange, name); + } + + protected void writeBodyAsUtf8(HttpServerExchange exchange, String body) { + exchange.getResponseSender().send(body, StandardCharsets.UTF_8); + } + + protected T parseJsonTo(HttpServerExchange exchange, Class type) { + try { + return GsonUtil.get().fromJson(IOUtils.toString(exchange.getInputStream(), StandardCharsets.UTF_8), type); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + protected JsonObject parseJsonObject(HttpServerExchange exchange, String key) { + try { + JsonObject base = GsonUtil.parseObj(IOUtils.toString(exchange.getInputStream(), StandardCharsets.UTF_8)); + return GsonUtil.getObj(base, key); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + protected void respond(HttpServerExchange ex, int statusCode, JsonElement bodyJson) { + respondJson(ex, statusCode, GsonUtil.get().toJson(bodyJson)); + } + + protected void respond(HttpServerExchange ex, JsonElement bodyJson) { + respond(ex, 200, bodyJson); + } + + protected void respondJson(HttpServerExchange ex, int status, String body) { + ex.setStatusCode(status); + ex.getResponseHeaders().put(HttpString.tryFromString("Content-Type"), "application/json"); + writeBodyAsUtf8(ex, body); + } + + protected void respondJson(HttpServerExchange ex, String body) { + respondJson(ex, 200, body); + } + + protected void respondJson(HttpServerExchange ex, Object body) { + respondJson(ex, GsonUtil.get().toJson(body)); + } + + protected JsonObject buildErrorBody(HttpServerExchange exchange, String errCode, String error) { + JsonObject obj = new JsonObject(); + obj.addProperty("errcode", errCode); + obj.addProperty("error", error); + obj.addProperty("success", false); + log.info("Request {} {} - Error {}: {}", exchange.getRequestMethod(), exchange.getRequestURL(), errCode, error); + return obj; + } + + protected void respond(HttpServerExchange ex, int status, String errCode, String error) { + respond(ex, status, buildErrorBody(ex, errCode, error)); + } + + protected void handleException(HttpServerExchange exchange, HttpMatrixException ex) { + respond(exchange, ex.getStatus(), buildErrorBody(exchange, ex.getErrorCode(), ex.getError())); + } + + protected void respond(HttpServerExchange exchange, Response upstream) { + exchange.setStatusCode(upstream.getStatus()); + upstream.getHeaders().forEach((key, value) -> exchange.getResponseHeaders().addAll(HttpString.tryFromString(key), value)); + writeBodyAsUtf8(exchange, upstream.getBody()); + } +} diff --git a/src/main/java/io/kamax/mxisd/controller/ProxyController.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/HomeserverProxyHandler.java similarity index 54% rename from src/main/java/io/kamax/mxisd/controller/ProxyController.java rename to src/main/java/io/kamax/mxisd/http/undertow/handler/HomeserverProxyHandler.java index 1744b80..1c33495 100644 --- a/src/main/java/io/kamax/mxisd/controller/ProxyController.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/HomeserverProxyHandler.java @@ -18,37 +18,38 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller; +package io.kamax.mxisd.http.undertow.handler; import io.kamax.mxisd.exception.AccessTokenNotFoundException; import io.kamax.mxisd.util.OptionalUtil; -import org.thymeleaf.util.StringUtils; +import io.undertow.server.HttpServerExchange; +import org.apache.commons.lang3.StringUtils; -import javax.servlet.http.HttpServletRequest; +import java.util.LinkedList; import java.util.Optional; -public class ProxyController { +public abstract class HomeserverProxyHandler extends BasicHttpHandler { - private final static String headerName = "Authorization"; - private final static String headerValuePrefix = "Bearer "; + protected final static String headerName = "Authorization"; + protected final static String headerValuePrefix = "Bearer "; private final static String parameterName = "access_token"; - Optional findAccessTokenInHeaders(HttpServletRequest request) { - return Optional.ofNullable(request.getHeader(headerName)) + Optional findAccessTokenInHeaders(HttpServerExchange exchange) { + return Optional.ofNullable(exchange.getRequestHeaders().getFirst(headerName)) .filter(header -> StringUtils.startsWith(header, headerValuePrefix)) .map(header -> header.substring(headerValuePrefix.length())); } - Optional findAccessTokenInQuery(HttpServletRequest request) { - return Optional.ofNullable(request.getParameter(parameterName)); + Optional findAccessTokenInQuery(HttpServerExchange exchange) { + return Optional.ofNullable(exchange.getQueryParameters().getOrDefault(parameterName, new LinkedList<>()).peekFirst()); } - public Optional findAccessToken(HttpServletRequest request) { - return OptionalUtil.findFirst(() -> findAccessTokenInHeaders(request), () -> findAccessTokenInQuery(request)); + public Optional findAccessToken(HttpServerExchange exchange) { + return OptionalUtil.findFirst(() -> findAccessTokenInHeaders(exchange), () -> findAccessTokenInQuery(exchange)); } - public String getAccessToken(HttpServletRequest request) { - return findAccessToken(request).orElseThrow(AccessTokenNotFoundException::new); + public String getAccessToken(HttpServerExchange exchange) { + return findAccessToken(exchange).orElseThrow(AccessTokenNotFoundException::new); } } diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/SaneHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/SaneHandler.java new file mode 100644 index 0000000..5e18341 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/SaneHandler.java @@ -0,0 +1,112 @@ +/* + * 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; + +import com.google.gson.JsonSyntaxException; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.exception.*; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; + +public class SaneHandler extends BasicHttpHandler { + + public static SaneHandler around(HttpHandler h) { + return new SaneHandler(h); + } + + private transient final Logger log = LoggerFactory.getLogger(SaneHandler.class); + + private HttpHandler child; + + public SaneHandler(HttpHandler child) { + this.child = child; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + exchange.startBlocking(); + + if (exchange.isInIoThread()) { + exchange.dispatch(this); + } else { + try { + child.handleRequest(exchange); + } catch (IllegalArgumentException e) { + respond(exchange, HttpStatus.SC_BAD_REQUEST, GsonUtil.makeObj("error", e.getMessage())); + } catch (BadRequestException e) { + respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_BAD_REQUEST", e.getMessage()); + } catch (MappingAlreadyExistsException e) { + respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_ALREADY_EXISTS", e.getMessage()); + } catch (JsonMemberNotFoundException e) { + respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_JSON_MISSING_KEYS", e.getMessage()); + } catch (InvalidResponseJsonException | JsonSyntaxException e) { + respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_INVALID_JSON", e.getMessage()); + } catch (InvalidCredentialsException e) { + respond(exchange, HttpStatus.SC_UNAUTHORIZED, "M_UNAUTHORIZED", e.getMessage()); + } catch (ObjectNotFoundException e) { + respond(exchange, HttpStatus.SC_NOT_FOUND, "M_NOT_FOUND", e.getMessage()); + } catch (NotImplementedException e) { + respond(exchange, HttpStatus.SC_NOT_IMPLEMENTED, "M_NOT_IMPLEMENTED", e.getMessage()); + } catch (FeatureNotAvailable e) { + if (StringUtils.isNotBlank(e.getInternalReason())) { + log.error("Feature not available: {}", e.getInternalReason()); + } + + handleException(exchange, e); + } catch (InternalServerError e) { + if (StringUtils.isNotBlank(e.getInternalReason())) { + log.error("Reference #{} - {}", e.getReference(), e.getInternalReason()); + } else { + log.error("Reference #{}", e); + } + + handleException(exchange, e); + } catch (RemoteLoginException e) { + if (e.getErrorBodyMsgResp() != null) { + respond(exchange, e.getStatus(), e.getErrorBodyMsgResp()); + } else { + handleException(exchange, e); + } + } catch (HttpMatrixException e) { + respond(exchange, e.getStatus(), buildErrorBody(exchange, e.getErrorCode(), e.getError())); + } catch (RuntimeException e) { + log.error("Unknown error when handling {}", exchange.getRequestURL(), e); + respond(exchange, HttpStatus.SC_INTERNAL_SERVER_ERROR, buildErrorBody(exchange, + "M_UNKNOWN", + StringUtils.defaultIfBlank( + e.getMessage(), + "An internal server error occurred. If this error persists, please contact support with reference #" + + Instant.now().toEpochMilli() + ) + )); + } finally { + exchange.endExchange(); + } + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/ApplicationServiceHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/ApplicationServiceHandler.java new file mode 100644 index 0000000..7bc7981 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/ApplicationServiceHandler.java @@ -0,0 +1,38 @@ +/* + * 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.as.v1; + +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.undertow.server.HttpServerExchange; + +import java.util.LinkedList; +import java.util.Optional; + +public abstract class ApplicationServiceHandler extends BasicHttpHandler { + + protected String getToken(HttpServerExchange ex) { + return Optional.ofNullable(ex.getQueryParameters() + .getOrDefault("access_token", new LinkedList<>()) + .peekFirst() + ).orElse(""); + } + +} diff --git a/src/main/java/io/kamax/mxisd/config/AsyncConfig.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsNotFoundHandler.java similarity index 60% rename from src/main/java/io/kamax/mxisd/config/AsyncConfig.java rename to src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsNotFoundHandler.java index 1736c1e..ed1e77b 100644 --- a/src/main/java/io/kamax/mxisd/config/AsyncConfig.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsNotFoundHandler.java @@ -18,19 +18,25 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.config; +package io.kamax.mxisd.http.undertow.handler.as.v1; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import io.kamax.mxisd.as.AppSvcManager; +import io.kamax.mxisd.exception.NotFoundException; +import io.undertow.server.HttpServerExchange; -@Configuration -public class AsyncConfig extends WebMvcConfigurerAdapter { +public class AsNotFoundHandler extends ApplicationServiceHandler { + + private final AppSvcManager app; + + public AsNotFoundHandler(AppSvcManager app) { + this.app = app; + } @Override - public void configureAsyncSupport(AsyncSupportConfigurer configurer) { - configurer.setDefaultTimeout(60 * 60 * 1000); // 1h in milliseconds - super.configureAsyncSupport(configurer); + public void handleRequest(HttpServerExchange exchange) { + app.withToken(getToken(exchange)); + + throw new NotFoundException(); } } diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsTransactionHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsTransactionHandler.java new file mode 100644 index 0000000..9bb65fb --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/as/v1/AsTransactionHandler.java @@ -0,0 +1,46 @@ +/* + * 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.as.v1; + +import io.kamax.mxisd.as.AppSvcManager; +import io.undertow.server.HttpServerExchange; + +import java.util.LinkedList; + +public class AsTransactionHandler extends ApplicationServiceHandler { + + public static final String ID = "txnId"; + public static final String Path = "/_matrix/app/v1/transactions/{" + ID + "}"; + + private final AppSvcManager app; + + public AsTransactionHandler(AppSvcManager app) { + this.app = app; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + String txnId = exchange.getQueryParameters().getOrDefault(ID, new LinkedList<>()).peekFirst(); + respondJson(exchange, app.withToken(getToken(exchange)) + .processTransaction(txnId, exchange.getInputStream()).get()); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/RestAuthHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/RestAuthHandler.java new file mode 100644 index 0000000..6db83aa --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/RestAuthHandler.java @@ -0,0 +1,70 @@ +/* + * 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.auth; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.auth.AuthManager; +import io.kamax.mxisd.auth.UserAuthResult; +import io.kamax.mxisd.exception.JsonMemberNotFoundException; +import io.kamax.mxisd.http.io.CredentialsValidationResponse; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RestAuthHandler extends BasicHttpHandler { + + public static final String Path = "/_matrix-internal/identity/v1/check_credentials"; + + private transient final Logger log = LoggerFactory.getLogger(RestAuthHandler.class); + + private AuthManager mgr; + + public RestAuthHandler(AuthManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + JsonObject authData = parseJsonObject(exchange, "user"); + if (!authData.has("id") || !authData.has("password")) { + throw new JsonMemberNotFoundException("Missing id or password keys"); + } + + String id = GsonUtil.getStringOrThrow(authData, "id"); + log.info("Requested to check credentials for {}", id); + String password = GsonUtil.getStringOrThrow(authData, "password"); + + UserAuthResult result = mgr.authenticate(id, password); + CredentialsValidationResponse response = new CredentialsValidationResponse(result.isSuccess()); + + if (result.isSuccess()) { + response.setDisplayName(result.getDisplayName()); + response.getProfile().setThreePids(result.getThreePids()); + } + + JsonElement authObj = GsonUtil.get().toJsonTree(response); + respond(exchange, GsonUtil.makeObj("auth", authObj)); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginGetHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginGetHandler.java new file mode 100644 index 0000000..9f7bf63 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginGetHandler.java @@ -0,0 +1,52 @@ +/* + * 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.auth.v1; + +import io.kamax.mxisd.auth.AuthManager; +import io.undertow.server.HttpServerExchange; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; + +import java.net.URI; + +public class LoginGetHandler extends LoginHandler { + + private AuthManager mgr; + private CloseableHttpClient client; + + public LoginGetHandler(AuthManager mgr, CloseableHttpClient client) { + this.mgr = mgr; + this.client = client; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + URI target = URI.create(exchange.getRequestURL()); + + try (CloseableHttpResponse hsResponse = client.execute(new HttpGet(mgr.resolveProxyUrl(target)))) { + // TODO deal with headers, content-type, encoding, etc. + respondJson(exchange, hsResponse.getStatusLine().getStatusCode(), EntityUtils.toString(hsResponse.getEntity())); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginHandler.java new file mode 100644 index 0000000..afdca34 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginHandler.java @@ -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 . + */ + +package io.kamax.mxisd.http.undertow.handler.auth.v1; + +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; + +public abstract class LoginHandler extends BasicHttpHandler { + + public static final String Path = "/_matrix/client/r0/login"; + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginPostHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginPostHandler.java new file mode 100644 index 0000000..c4699c9 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/auth/v1/LoginPostHandler.java @@ -0,0 +1,47 @@ +/* + * 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.auth.v1; + +import io.kamax.mxisd.auth.AuthManager; +import io.undertow.server.HttpServerExchange; +import org.apache.commons.io.IOUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; + +public class LoginPostHandler extends LoginHandler { + + private AuthManager mgr; + + public LoginPostHandler(AuthManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + respondJson(exchange, mgr.proxyLogin( + URI.create(exchange.getRequestURL()), + IOUtils.toString(exchange.getInputStream(), StandardCharsets.UTF_8) + ) + ); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/directory/v1/UserDirectorySearchHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/directory/v1/UserDirectorySearchHandler.java new file mode 100644 index 0000000..5f948c1 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/directory/v1/UserDirectorySearchHandler.java @@ -0,0 +1,52 @@ +/* + * 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.directory.v1; + +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.directory.DirectoryManager; +import io.kamax.mxisd.http.io.UserDirectorySearchRequest; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; +import io.kamax.mxisd.http.undertow.handler.HomeserverProxyHandler; +import io.undertow.server.HttpServerExchange; + +import java.net.URI; + +public class UserDirectorySearchHandler extends HomeserverProxyHandler { + + public static final String Path = "/_matrix/client/r0/user_directory/search"; + + private DirectoryManager mgr; + + public UserDirectorySearchHandler(DirectoryManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + String accessToken = getAccessToken(exchange); + UserDirectorySearchRequest searchQuery = parseJsonTo(exchange, UserDirectorySearchRequest.class); + URI target = URI.create(exchange.getRequestURL()); + UserDirectorySearchResult result = mgr.search(target, accessToken, searchQuery.getSearchTerm()); + + respondJson(exchange, GsonUtil.get().toJson(result)); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/BulkLookupHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/BulkLookupHandler.java new file mode 100644 index 0000000..2022fee --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/BulkLookupHandler.java @@ -0,0 +1,70 @@ +/* + * 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.http.IsAPIv1; +import io.kamax.mxisd.http.io.identity.ClientBulkLookupAnswer; +import io.kamax.mxisd.http.io.identity.ClientBulkLookupRequest; +import io.kamax.mxisd.lookup.BulkLookupRequest; +import io.kamax.mxisd.lookup.ThreePidMapping; +import io.kamax.mxisd.lookup.strategy.LookupStrategy; +import io.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class BulkLookupHandler extends LookupHandler { + + public static final String Path = IsAPIv1.Base + "/bulk_lookup"; + + private transient final Logger log = LoggerFactory.getLogger(SingleLookupHandler.class); + + private LookupStrategy strategy; + + public BulkLookupHandler(LookupStrategy strategy) { + this.strategy = strategy; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + ClientBulkLookupRequest input = parseJsonTo(exchange, ClientBulkLookupRequest.class); + BulkLookupRequest lookupRequest = new BulkLookupRequest(); + setRequesterInfo(lookupRequest, exchange); + log.info("Got bulk lookup request from {} with client {} - Is recursive? {}", + lookupRequest.getRequester(), lookupRequest.getUserAgent(), lookupRequest.isRecursive()); + + List mappings = new ArrayList<>(); + for (List mappingRaw : input.getThreepids()) { + ThreePidMapping mapping = new ThreePidMapping(); + mapping.setMedium(mappingRaw.get(0)); + mapping.setValue(mappingRaw.get(1)); + mappings.add(mapping); + } + lookupRequest.setMappings(mappings); + + ClientBulkLookupAnswer answer = new ClientBulkLookupAnswer(); + answer.addAll(strategy.find(lookupRequest)); + respondJson(exchange, answer); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java new file mode 100644 index 0000000..eaa802c --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java @@ -0,0 +1,41 @@ +/* + * 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.http.IsAPIv1; +import io.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EphemeralKeyIsValidHandler extends KeyIsValidHandler { + + public static final String Path = IsAPIv1.Base + "/pubkey/ephemeral/isvalid"; + + private transient final Logger log = LoggerFactory.getLogger(EphemeralKeyIsValidHandler.class); + + @Override + public void handleRequest(HttpServerExchange exchange) { + log.warn("Ephemeral key was requested but no ephemeral key are generated, replying not valid"); + + respondJson(exchange, invalidKey); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/HelloHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/HelloHandler.java new file mode 100644 index 0000000..4b018fa --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/HelloHandler.java @@ -0,0 +1,36 @@ +/* + * 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.http.IsAPIv1; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.undertow.server.HttpServerExchange; + +public class HelloHandler extends BasicHttpHandler { + + public static final String Path = IsAPIv1.Base; + + @Override + public void handleRequest(HttpServerExchange exchange) { + respondJson(exchange, "{}"); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java new file mode 100644 index 0000000..ba61f3e --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java @@ -0,0 +1,62 @@ +/* + * 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 com.google.gson.JsonObject; +import io.kamax.matrix.crypto.KeyManager; +import io.kamax.mxisd.exception.BadRequestException; +import io.kamax.mxisd.http.IsAPIv1; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KeyGetHandler extends BasicHttpHandler { + + public static final String Key = "key"; + public static final String Path = IsAPIv1.Base + "/pubkey/{key}"; + + private transient final Logger log = LoggerFactory.getLogger(KeyGetHandler.class); + + private KeyManager mgr; + + public KeyGetHandler(KeyManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String key = getQueryParameter(exchange, Key); + String[] v = key.split(":", 1); + String keyType = v[0]; + int keyId = Integer.parseInt(v[1]); + + if (!"ed25519".contentEquals(keyType)) { + throw new BadRequestException("Invalid algorithm: " + keyType); + } + + log.info("Key {}:{} was requested", keyType, keyId); + JsonObject obj = new JsonObject(); + obj.addProperty("public_key", mgr.getPublicKeyBase64(keyId)); + respond(exchange, obj); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyIsValidHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyIsValidHandler.java new file mode 100644 index 0000000..acbac76 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyIsValidHandler.java @@ -0,0 +1,32 @@ +/* + * 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.matrix.json.GsonUtil; +import io.kamax.mxisd.http.io.identity.KeyValidityJson; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; + +public abstract class KeyIsValidHandler extends BasicHttpHandler { + + protected final String validKey = GsonUtil.get().toJson(new KeyValidityJson(true)); + protected final String invalidKey = GsonUtil.get().toJson(new KeyValidityJson(false)); + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/LookupHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/LookupHandler.java new file mode 100644 index 0000000..ec623fa --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/LookupHandler.java @@ -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 . + */ + +package io.kamax.mxisd.http.undertow.handler.identity.v1; + +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.kamax.mxisd.lookup.ALookupRequest; +import io.undertow.server.HttpServerExchange; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetSocketAddress; +import java.util.Arrays; + +public abstract class LookupHandler extends BasicHttpHandler { + + private transient final Logger log = LoggerFactory.getLogger(LookupHandler.class); + + protected void setRequesterInfo(ALookupRequest lookup, HttpServerExchange exchange) { + InetSocketAddress addr = (InetSocketAddress) exchange.getConnection().getPeerAddress(); + lookup.setRequester(addr.getAddress().getHostAddress()); + String xff = exchange.getRequestHeaders().getFirst("X-Forwarded-For"); + log.debug("XFF header: {}", xff); + lookup.setRecursive(StringUtils.isBlank(xff)); + if (!lookup.isRecursive()) { + lookup.setRecurseHosts(Arrays.asList(xff.split(","))); + lookup.setRequester(lookup.getRecurseHosts().get(lookup.getRecurseHosts().size() - 1)); + } + + lookup.setUserAgent(exchange.getRequestHeaders().getFirst("User-Agent")); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java new file mode 100644 index 0000000..171c2b0 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java @@ -0,0 +1,52 @@ +/* + * 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.matrix.crypto.KeyManager; +import io.kamax.mxisd.http.IsAPIv1; +import io.undertow.server.HttpServerExchange; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RegularKeyIsValidHandler extends KeyIsValidHandler { + + public static final String Path = IsAPIv1.Base + "/pubkey/isvalid"; + + private transient final Logger log = LoggerFactory.getLogger(RegularKeyIsValidHandler.class); + + private KeyManager mgr; + + public RegularKeyIsValidHandler(KeyManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String pubKey = getQueryParameter(exchange, "public_key"); + log.info("Validating public key {}", pubKey); + + // TODO do in manager + boolean valid = StringUtils.equals(pubKey, mgr.getPublicKeyBase64(mgr.getCurrentIndex())); + respondJson(exchange, valid ? validKey : invalidKey); + } + +} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteIdentityAPIv1.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java similarity index 95% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteIdentityAPIv1.java rename to src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java index cb2ab1c..71bd4ff 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/remote/RemoteIdentityAPIv1.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteIdentityAPIv1.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1.remote; +package io.kamax.mxisd.http.undertow.handler.identity.v1; public class RemoteIdentityAPIv1 { 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 new file mode 100644 index 0000000..ab338c0 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionCheckHandler.java @@ -0,0 +1,62 @@ +/* + * 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.undertow.server.HttpServerExchange; +import org.apache.commons.io.IOUtils; + +import java.io.FileInputStream; +import java.nio.charset.StandardCharsets; + +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"); + + try { + FileInputStream f = new FileInputStream(viewCfg.getSession().getRemote().getOnCheck().getSuccess()); + String viewData = IOUtils.toString(f, StandardCharsets.UTF_8); + + mgr.validateRemote(sid, secret); + + writeBodyAsUtf8(exchange, viewData); + } catch (SessionNotValidatedException e) { + FileInputStream f = new FileInputStream(viewCfg.getSession().getRemote().getOnCheck().getFailure()); + String viewData = IOUtils.toString(f, StandardCharsets.UTF_8); + 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 new file mode 100644 index 0000000..e04eb9c --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RemoteSessionStartHandler.java @@ -0,0 +1,55 @@ +/* + * 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.undertow.server.HttpServerExchange; +import org.apache.commons.io.IOUtils; + +import java.io.FileInputStream; +import java.nio.charset.StandardCharsets; + +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); + + FileInputStream f = new FileInputStream(viewCfg.getSession().getRemote().getOnRequest().getSuccess()); + String rawData = IOUtils.toString(f, StandardCharsets.UTF_8); + 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 new file mode 100644 index 0000000..a8446ae --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionStartHandler.java @@ -0,0 +1,87 @@ +/* + * 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 com.google.gson.JsonObject; +import io.kamax.matrix.ThreePid; +import io.kamax.matrix.ThreePidMedium; +import io.kamax.mxisd.http.IsAPIv1; +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.undertow.server.HttpServerExchange; +import org.apache.http.HttpStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SessionStartHandler extends BasicHttpHandler { + + public static final String Medium = "medium"; + public static final String Path = IsAPIv1.Base + "/validate/{" + Medium + "}/requestToken"; + + private transient final Logger log = LoggerFactory.getLogger(SessionStartHandler.class); + + private SessionMananger mgr; + + public SessionStartHandler(SessionMananger mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String medium = getPathVariable(exchange, "medium"); + + if (ThreePidMedium.Email.is(medium)) { + SessionEmailTokenRequestJson req = parseJsonTo(exchange, SessionEmailTokenRequestJson.class); + ThreePid threepid = new ThreePid(req.getMedium(), req.getValue()); + + respondJson(exchange, new RequestTokenResponse(mgr.create( + getRemoteHostAddress(exchange), + threepid, + req.getSecret(), + req.getAttempt(), + req.getNextLink()))); + } else if (ThreePidMedium.PhoneNumber.is(medium)) { + SessionPhoneTokenRequestJson req = parseJsonTo(exchange, SessionPhoneTokenRequestJson.class); + ThreePid threepid = new ThreePid(req.getMedium(), req.getValue()); + + String sessionId = mgr.create( + getRemoteHostAddress(exchange), + threepid, + req.getSecret(), + req.getAttempt(), + req.getNextLink()); + + JsonObject res = new JsonObject(); + res.addProperty("sid", sessionId); + res.addProperty(threepid.getMedium(), threepid.getAddress()); + respond(exchange, res); + } else { + JsonObject obj = new JsonObject(); + obj.addProperty("errcode", "M_INVALID_3PID_TYPE"); + obj.addProperty("error", medium + " is not supported as a 3PID type"); + respond(exchange, HttpStatus.SC_BAD_REQUEST, obj); + } + } + +} 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 new file mode 100644 index 0000000..69472fe --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidBindHandler.java @@ -0,0 +1,71 @@ +/* + * 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 com.google.gson.JsonObject; +import io.kamax.mxisd.exception.BadRequestException; +import io.kamax.mxisd.http.IsAPIv1; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.kamax.mxisd.invitation.InvitationManager; +import io.kamax.mxisd.session.SessionMananger; +import io.undertow.server.HttpServerExchange; +import org.apache.http.HttpStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SessionTpidBindHandler extends BasicHttpHandler { + + public static final String Path = IsAPIv1.Base + "/3pid/bind"; + + private transient final Logger log = LoggerFactory.getLogger(SessionTpidBindHandler.class); + + private SessionMananger mgr; + private InvitationManager invMgr; + + public SessionTpidBindHandler(SessionMananger mgr, InvitationManager invMgr) { + this.mgr = mgr; + this.invMgr = invMgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String sid = getQueryParameter(exchange, "sid"); + String secret = getQueryParameter(exchange, "client_secret"); + String mxid = getQueryParameter(exchange, "mxid"); + + try { + mgr.bind(sid, secret, mxid); + respond(exchange, new JsonObject()); + } catch (BadRequestException e) { + log.info("requested session was not validated"); + + JsonObject obj = new JsonObject(); + obj.addProperty("errcode", "M_SESSION_NOT_VALIDATED"); + obj.addProperty("error", e.getMessage()); + respond(exchange, HttpStatus.SC_BAD_REQUEST, obj); + } finally { + // If a user registers, there is no standard login event. Instead, this is the only way to trigger + // resolution at an appropriate time. Meh at synapse/Riot! + invMgr.lookupMappingsForInvites(); + } + } + +} 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 new file mode 100644 index 0000000..8c1e003 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionTpidGetValidatedHandler.java @@ -0,0 +1,65 @@ +/* + * 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 com.google.gson.JsonObject; +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.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SessionTpidGetValidatedHandler extends BasicHttpHandler { + + public static final String Path = IsAPIv1.Base + "/3pid/getValidated3pid"; + + private transient final Logger log = LoggerFactory.getLogger(SessionTpidGetValidatedHandler.class); + + private SessionMananger mgr; + + public SessionTpidGetValidatedHandler(SessionMananger mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String sid = getQueryParameter(exchange, "sid"); + String secret = getQueryParameter(exchange, "client_secret"); + + try { + ThreePidValidation pid = mgr.getValidated(sid, secret); + + JsonObject obj = new JsonObject(); + obj.addProperty("medium", pid.getMedium()); + obj.addProperty("address", pid.getAddress()); + obj.addProperty("validated_at", pid.getValidation().toEpochMilli()); + + respond(exchange, obj); + } catch (SessionNotValidatedException e) { + log.info("Session {} was requested but has not yet been validated", sid); + throw e; + } + } + +} 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 new file mode 100644 index 0000000..d0f6c08 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SessionValidateHandler.java @@ -0,0 +1,124 @@ +/* + * 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.ServerConfig; +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.ValidationResult; +import io.undertow.server.HttpServerExchange; +import io.undertow.util.HttpString; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +public class SessionValidateHandler extends BasicHttpHandler { + + public static final String Path = IsAPIv1.Base + "/validate/{medium}/submitToken"; + + private transient final Logger log = LoggerFactory.getLogger(SessionValidateHandler.class); + + private SessionMananger mgr; + private ServerConfig srvCfg; + private ViewConfig viewCfg; + + public SessionValidateHandler(SessionMananger mgr, ServerConfig srvCfg, ViewConfig viewCfg) { + this.mgr = mgr; + this.srvCfg = srvCfg; + this.viewCfg = viewCfg; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String medium = getQueryParameter(exchange, "medium"); + String sid = getQueryParameter(exchange, "sid"); + String secret = getQueryParameter(exchange, "client_secret"); + String token = getQueryParameter(exchange, "token"); + + boolean isHtmlRequest = false; + for (String v : exchange.getRequestHeaders().get("Accept")) { + if (StringUtils.startsWithIgnoreCase(v, "text/html")) { + isHtmlRequest = true; + break; + } + } + + if (isHtmlRequest) { + handleHtmlRequest(exchange, medium, sid, secret, token); + } else { + handleJsonRequest(exchange, medium, sid, secret, token); + } + } + + public 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); + if (r.getNextUrl().isPresent()) { + String url = r.getNextUrl().get(); + try { + url = new URL(url).toString(); + } catch (MalformedURLException e) { + log.info("Session next URL {} is not a valid one, will prepend public URL {}", url, srvCfg.getPublicUrl()); + url = srvCfg.getPublicUrl() + r.getNextUrl().get(); + } + log.info("Session {} validation: next URL is present, redirecting to {}", sid, url); + exchange.setStatusCode(302); + exchange.getResponseHeaders().add(HttpString.tryFromString("Location"), url); + } else { + try { + if (r.isCanRemote()) { + FileInputStream f = new FileInputStream(viewCfg.getSession().getLocalRemote().getOnTokenSubmit().getSuccess()); + String url = srvCfg.getPublicUrl() + RemoteIdentityAPIv1.getRequestToken(r.getSession().getId(), r.getSession().getSecret()); + String rawData = IOUtils.toString(f, StandardCharsets.UTF_8); + String data = rawData.replace("${remoteSessionLink}", url); + writeBodyAsUtf8(exchange, data); + } else { + FileInputStream f = new FileInputStream(viewCfg.getSession().getLocalRemote().getOnTokenSubmit().getSuccess()); + String data = IOUtils.toString(f, StandardCharsets.UTF_8); + writeBodyAsUtf8(exchange, data); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public void handleJsonRequest(HttpServerExchange exchange, String medium, String sid, String secret, String token) { + log.info("Requested: {}", exchange.getRequestURL()); + + ValidationResult r = 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/http/undertow/handler/identity/v1/SingleLookupHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java new file mode 100644 index 0000000..e341057 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java @@ -0,0 +1,81 @@ +/* + * 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 com.google.gson.JsonObject; +import io.kamax.matrix.crypto.SignatureManager; +import io.kamax.matrix.event.EventKey; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.matrix.json.MatrixJson; +import io.kamax.mxisd.http.IsAPIv1; +import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson; +import io.kamax.mxisd.lookup.SingleLookupReply; +import io.kamax.mxisd.lookup.SingleLookupRequest; +import io.kamax.mxisd.lookup.strategy.LookupStrategy; +import io.undertow.server.HttpServerExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Optional; + +public class SingleLookupHandler extends LookupHandler { + + public static final String Path = IsAPIv1.Base + "/lookup"; + + private transient final Logger log = LoggerFactory.getLogger(SingleLookupHandler.class); + + private LookupStrategy strategy; + private SignatureManager signMgr; + + public SingleLookupHandler(LookupStrategy strategy, SignatureManager signMgr) { + this.strategy = strategy; + this.signMgr = signMgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String medium = getQueryParameter(exchange, "medium"); + String address = getQueryParameter(exchange, "address"); + + SingleLookupRequest lookupRequest = new SingleLookupRequest(); + setRequesterInfo(lookupRequest, exchange); + lookupRequest.setType(medium); + lookupRequest.setThreePid(address); + + log.info("Got single lookup request from {} with client {} - Is recursive? {}", + lookupRequest.getRequester(), lookupRequest.getUserAgent(), lookupRequest.isRecursive()); + + Optional lookupOpt = strategy.find(lookupRequest); + if (!lookupOpt.isPresent()) { + log.info("No mapping was found, return empty JSON object"); + respondJson(exchange, "{}"); + } else { + SingleLookupReply lookup = lookupOpt.get(); + + // FIXME signing should be done in the business model, not in the controller + JsonObject obj = GsonUtil.makeObj(new SingeLookupReplyJson(lookup)); + obj.add(EventKey.Signatures.get(), signMgr.signMessageGson(MatrixJson.encodeCanonical(obj))); + + respondJson(exchange, obj); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java new file mode 100644 index 0000000..907939c --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java @@ -0,0 +1,76 @@ +/* + * 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.matrix.MatrixID; +import io.kamax.matrix.crypto.KeyManager; +import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.http.IsAPIv1; +import io.kamax.mxisd.http.io.identity.ThreePidInviteReplyIO; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.kamax.mxisd.invitation.IThreePidInvite; +import io.kamax.mxisd.invitation.IThreePidInviteReply; +import io.kamax.mxisd.invitation.InvitationManager; +import io.kamax.mxisd.invitation.ThreePidInvite; +import io.undertow.server.HttpServerExchange; + +import java.util.Deque; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class StoreInviteHandler extends BasicHttpHandler { + + public static final String Path = IsAPIv1.Base + "/store-invite"; + + private ServerConfig cfg; + private InvitationManager invMgr; + private KeyManager keyMgr; + + public StoreInviteHandler(ServerConfig cfg, InvitationManager invMgr, KeyManager keyMgr) { + this.cfg = cfg; + this.invMgr = invMgr; + this.keyMgr = keyMgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + Map parameters = new HashMap<>(); + + for (Map.Entry> entry : exchange.getQueryParameters().entrySet()) { + if (Objects.nonNull(entry.getValue().peekFirst())) { + parameters.put(entry.getKey(), entry.getValue().peekFirst()); + } + } + + // TODO test with missing parameters to see behaviour + String sender = parameters.get("sender"); + String medium = parameters.get("medium"); + String address = parameters.get("address"); + String roomId = parameters.get("room_id"); + + IThreePidInvite invite = new ThreePidInvite(MatrixID.asAcceptable(sender), medium, address, roomId, parameters); + IThreePidInviteReply reply = invMgr.storeInvite(invite); + + respondJson(exchange, new ThreePidInviteReplyIO(reply, keyMgr.getPublicKeyBase64(keyMgr.getCurrentIndex()), cfg.getPublicUrl())); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/InternalProfileHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/InternalProfileHandler.java new file mode 100644 index 0000000..a333e67 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/InternalProfileHandler.java @@ -0,0 +1,54 @@ +/* + * 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.profile.v1; + +import io.kamax.matrix.MatrixID; +import io.kamax.matrix._MatrixID; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.profile.ProfileManager; +import io.undertow.server.HttpServerExchange; +import org.apache.http.client.methods.HttpGet; + +import java.net.URI; +import java.util.Optional; + +public class InternalProfileHandler extends ProfileHandler { + + public static final String Path = "/_matrix-internal/profile/v1/{" + UserID + "}"; + + public InternalProfileHandler(ProfileManager mgr) { + super(mgr); + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String userId = getQueryParameter(exchange, UserID); + _MatrixID mxId = MatrixID.asAcceptable(userId); + URI target = URI.create(exchange.getRequestURI()); + Optional accessTokenOpt = findAccessToken(exchange); + + HttpGet reqOut = new HttpGet(target); + accessTokenOpt.ifPresent(accessToken -> reqOut.addHeader(headerName, headerValuePrefix + accessToken)); + + respond(exchange, GsonUtil.makeObj("roles", GsonUtil.asArray(mgr.getRoles(mxId)))); + } + +} diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/ProfileHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/ProfileHandler.java new file mode 100644 index 0000000..9ceb2ce --- /dev/null +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/profile/v1/ProfileHandler.java @@ -0,0 +1,59 @@ +/* + * 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.profile.v1; + +import io.kamax.matrix.MatrixID; +import io.kamax.matrix._MatrixID; +import io.kamax.mxisd.http.undertow.handler.HomeserverProxyHandler; +import io.kamax.mxisd.profile.ProfileManager; +import io.kamax.mxisd.proxy.Response; +import io.undertow.server.HttpServerExchange; +import org.apache.http.client.methods.HttpGet; + +import java.net.URI; +import java.util.Optional; + +public class ProfileHandler extends HomeserverProxyHandler { + + public static final String UserID = "userId"; + public static final String Path = "/_matrix/client/r0/profile/{" + UserID + "}"; + + protected ProfileManager mgr; + + public ProfileHandler(ProfileManager mgr) { + this.mgr = mgr; + } + + @Override + public void handleRequest(HttpServerExchange exchange) { + String userId = getQueryParameter(exchange, UserID); + _MatrixID mxId = MatrixID.asAcceptable(userId); + URI target = URI.create(exchange.getRequestURL()); + Optional accessTokenOpt = findAccessToken(exchange); + + HttpGet reqOut = new HttpGet(target); + accessTokenOpt.ifPresent(accessToken -> reqOut.addHeader(headerName, headerValuePrefix + accessToken)); + + Response res = mgr.enhance(mxId, reqOut); + respond(exchange, res); + } + +} diff --git a/src/main/java/io/kamax/mxisd/controller/identity/v1/StatusController.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/status/StatusHandler.java similarity index 61% rename from src/main/java/io/kamax/mxisd/controller/identity/v1/StatusController.java rename to src/main/java/io/kamax/mxisd/http/undertow/handler/status/StatusHandler.java index d5f833b..a5dfa0e 100644 --- a/src/main/java/io/kamax/mxisd/controller/identity/v1/StatusController.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/status/StatusHandler.java @@ -1,6 +1,6 @@ /* * mxisd - Matrix Identity Server Daemon - * Copyright (C) 2017 Kamax Sarl + * Copyright (C) 2018 Kamax Sarl * * https://www.kamax.io/ * @@ -18,24 +18,18 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.controller.identity.v1; +package io.kamax.mxisd.http.undertow.handler.status; -import com.google.gson.Gson; import com.google.gson.JsonObject; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; +import io.undertow.server.HttpServerExchange; -@RestController -@CrossOrigin -@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class StatusController { +public class StatusHandler extends BasicHttpHandler { - private Gson gson = new Gson(); + public static final String Path = "/_matrix/identity/status"; - @RequestMapping(value = "/_matrix/identity/status") - public String getStatus() { + @Override + public void handleRequest(HttpServerExchange exchange) { // TODO link to backend JsonObject status = new JsonObject(); status.addProperty("health", "OK"); @@ -43,7 +37,7 @@ public class StatusController { JsonObject obj = new JsonObject(); obj.add("status", status); - return gson.toJson(obj); + respond(exchange, obj); } } diff --git a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java index e1abe9f..8574e3f 100644 --- a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java +++ b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java @@ -49,8 +49,6 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.xbill.DNS.*; import javax.annotation.PostConstruct; @@ -66,36 +64,29 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; -@Component public class InvitationManager { - private Logger log = LoggerFactory.getLogger(InvitationManager.class); + private transient final Logger log = LoggerFactory.getLogger(InvitationManager.class); - private Map invitations = new ConcurrentHashMap<>(); - - @Autowired private InvitationConfig cfg; - - @Autowired private IStorage storage; - - @Autowired private LookupStrategy lookupMgr; - - @Autowired private SignatureManager signMgr; - - @Autowired private FederationDnsOverwrite dns; - private NotificationManager notifMgr; private CloseableHttpClient client; private Gson gson; private Timer refreshTimer; - @Autowired - public InvitationManager(NotificationManager notifMgr) { + private Map invitations = new ConcurrentHashMap<>(); + + public InvitationManager(InvitationConfig cfg, IStorage storage, LookupStrategy lookupMgr, SignatureManager signMgr, FederationDnsOverwrite dns, NotificationManager notifMgr) { + this.cfg = cfg; + this.storage = storage; + this.lookupMgr = lookupMgr; + this.signMgr = signMgr; + this.dns = dns; this.notifMgr = notifMgr; } diff --git a/src/main/java/io/kamax/mxisd/lookup/SingleLookupReply.java b/src/main/java/io/kamax/mxisd/lookup/SingleLookupReply.java index 0c13f13..2d7bcb3 100644 --- a/src/main/java/io/kamax/mxisd/lookup/SingleLookupReply.java +++ b/src/main/java/io/kamax/mxisd/lookup/SingleLookupReply.java @@ -24,7 +24,7 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import io.kamax.matrix.MatrixID; import io.kamax.matrix._MatrixID; -import io.kamax.mxisd.controller.identity.v1.io.SingeLookupReplyJson; +import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson; import java.time.Instant; diff --git a/src/main/java/io/kamax/mxisd/lookup/ThreePidProviders.java b/src/main/java/io/kamax/mxisd/lookup/ThreePidProviders.java new file mode 100644 index 0000000..50bd21a --- /dev/null +++ b/src/main/java/io/kamax/mxisd/lookup/ThreePidProviders.java @@ -0,0 +1,42 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.lookup; + +import io.kamax.mxisd.lookup.provider.IThreePidProvider; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class ThreePidProviders { + + private static final List> suppliers = new ArrayList<>(); + + public static void register(Supplier supplier) { + suppliers.add(supplier); + } + + public static List get() { + return suppliers.stream().map(Supplier::get).collect(Collectors.toList()); + } + +} diff --git a/src/main/java/io/kamax/mxisd/lookup/provider/BridgeFetcher.java b/src/main/java/io/kamax/mxisd/lookup/provider/BridgeFetcher.java index 86b79e4..93dcde8 100644 --- a/src/main/java/io/kamax/mxisd/lookup/provider/BridgeFetcher.java +++ b/src/main/java/io/kamax/mxisd/lookup/provider/BridgeFetcher.java @@ -28,24 +28,23 @@ import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.Collections; import java.util.List; import java.util.Optional; -@Component public class BridgeFetcher implements IBridgeFetcher { - private Logger log = LoggerFactory.getLogger(BridgeFetcher.class); + private transient final Logger log = LoggerFactory.getLogger(BridgeFetcher.class); - @Autowired private RecursiveLookupBridgeConfig cfg; - - @Autowired private RemoteIdentityServerFetcher fetcher; + public BridgeFetcher(RecursiveLookupBridgeConfig cfg, RemoteIdentityServerFetcher fetcher) { + this.cfg = cfg; + this.fetcher = fetcher; + } + @Override public Optional find(SingleLookupRequest request) { Optional mediumUrl = Optional.ofNullable(cfg.getMappings().get(request.getType())); diff --git a/src/main/java/io/kamax/mxisd/lookup/provider/DnsLookupProvider.java b/src/main/java/io/kamax/mxisd/lookup/provider/DnsLookupProvider.java index 7ad392b..ed51e8f 100644 --- a/src/main/java/io/kamax/mxisd/lookup/provider/DnsLookupProvider.java +++ b/src/main/java/io/kamax/mxisd/lookup/provider/DnsLookupProvider.java @@ -30,24 +30,23 @@ import io.kamax.mxisd.matrix.IdentityServerUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; -@Component class DnsLookupProvider implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(DnsLookupProvider.class); + private transient final Logger log = LoggerFactory.getLogger(DnsLookupProvider.class); - @Autowired - private MatrixConfig mxCfg; - - @Autowired + private MatrixConfig cfg; private IRemoteIdentityServerFetcher fetcher; + public DnsLookupProvider(MatrixConfig cfg, IRemoteIdentityServerFetcher fetcher) { + this.cfg = cfg; + this.fetcher = fetcher; + } + @Override public boolean isEnabled() { return true; @@ -74,7 +73,7 @@ class DnsLookupProvider implements IThreePidProvider { // TODO use caching mechanism private Optional findIdentityServerForDomain(String domain) { - if (StringUtils.equals(mxCfg.getDomain(), domain)) { + if (StringUtils.equals(cfg.getDomain(), domain)) { log.info("We are authoritative for {}, no remote lookup", domain); return Optional.empty(); } diff --git a/src/main/java/io/kamax/mxisd/lookup/provider/ForwarderProvider.java b/src/main/java/io/kamax/mxisd/lookup/provider/ForwarderProvider.java index b4b747d..7d048d9 100644 --- a/src/main/java/io/kamax/mxisd/lookup/provider/ForwarderProvider.java +++ b/src/main/java/io/kamax/mxisd/lookup/provider/ForwarderProvider.java @@ -28,27 +28,25 @@ import io.kamax.mxisd.lookup.ThreePidMapping; import io.kamax.mxisd.lookup.fetcher.IRemoteIdentityServerFetcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Optional; -@Component -class ForwarderProvider implements IThreePidProvider { +public class ForwarderProvider implements IThreePidProvider { - private Logger log = LoggerFactory.getLogger(ForwarderProvider.class); + private transient final Logger log = LoggerFactory.getLogger(ForwarderProvider.class); - @Autowired private ForwardConfig cfg; - - @Autowired private MatrixConfig mxCfg; - - @Autowired private IRemoteIdentityServerFetcher fetcher; + public ForwarderProvider(ForwardConfig cfg, MatrixConfig mxCfg, IRemoteIdentityServerFetcher fetcher) { + this.cfg = cfg; + this.mxCfg = mxCfg; + this.fetcher = fetcher; + } + @Override public boolean isEnabled() { return true; diff --git a/src/main/java/io/kamax/mxisd/lookup/provider/RemoteIdentityServerFetcher.java b/src/main/java/io/kamax/mxisd/lookup/provider/RemoteIdentityServerFetcher.java index 36d0dc9..a288084 100644 --- a/src/main/java/io/kamax/mxisd/lookup/provider/RemoteIdentityServerFetcher.java +++ b/src/main/java/io/kamax/mxisd/lookup/provider/RemoteIdentityServerFetcher.java @@ -24,8 +24,8 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import io.kamax.matrix.json.GsonUtil; -import io.kamax.mxisd.controller.identity.v1.ClientBulkLookupRequest; import io.kamax.mxisd.exception.InvalidResponseJsonException; +import io.kamax.mxisd.http.io.identity.ClientBulkLookupRequest; import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupRequest; import io.kamax.mxisd.lookup.ThreePidMapping; @@ -41,10 +41,6 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; import java.io.IOException; import java.net.URISyntaxException; @@ -52,19 +48,20 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -@Component -@Scope("prototype") -@Lazy public class RemoteIdentityServerFetcher implements IRemoteIdentityServerFetcher { - private Logger log = LoggerFactory.getLogger(RemoteIdentityServerFetcher.class); + private transient final Logger log = LoggerFactory.getLogger(RemoteIdentityServerFetcher.class); + // FIXME remove private Gson gson = new Gson(); private GsonParser parser = new GsonParser(gson); - @Autowired private CloseableHttpClient client; + public RemoteIdentityServerFetcher(CloseableHttpClient client) { + this.client = client; + } + @Override public boolean isUsable(String remote) { return IdentityServerUtils.isUsable(remote); diff --git a/src/main/java/io/kamax/mxisd/lookup/strategy/RecursivePriorityLookupStrategy.java b/src/main/java/io/kamax/mxisd/lookup/strategy/RecursivePriorityLookupStrategy.java index a1c5c35..387dc47 100644 --- a/src/main/java/io/kamax/mxisd/lookup/strategy/RecursivePriorityLookupStrategy.java +++ b/src/main/java/io/kamax/mxisd/lookup/strategy/RecursivePriorityLookupStrategy.java @@ -21,18 +21,14 @@ package io.kamax.mxisd.lookup.strategy; import edazdarevic.commons.net.CIDRUtils; -import io.kamax.mxisd.config.BulkLookupConfig; -import io.kamax.mxisd.config.RecursiveLookupConfig; +import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.exception.ConfigurationException; import io.kamax.mxisd.lookup.*; import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher; import io.kamax.mxisd.lookup.provider.IThreePidProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; @@ -40,38 +36,31 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -@Component public class RecursivePriorityLookupStrategy implements LookupStrategy { - private Logger log = LoggerFactory.getLogger(RecursivePriorityLookupStrategy.class); + private transient final Logger log = LoggerFactory.getLogger(RecursivePriorityLookupStrategy.class); - private RecursiveLookupConfig cfg; - private BulkLookupConfig bulkCfg; + private MxisdConfig.Lookup cfg; private List providers; private IBridgeFetcher bridge; private List allowedCidr = new ArrayList<>(); - @Autowired - public RecursivePriorityLookupStrategy(RecursiveLookupConfig cfg, BulkLookupConfig bulkCfg, List providers, IBridgeFetcher bridge) { + public RecursivePriorityLookupStrategy(MxisdConfig.Lookup cfg, List providers, IBridgeFetcher bridge) { this.cfg = cfg; - this.bulkCfg = bulkCfg; 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()); - } - @PostConstruct - private void build() throws UnknownHostException { try { log.info("Found {} providers", providers.size()); providers.forEach(p -> log.info("\t- {}", p.getClass().getName())); providers.sort((o1, o2) -> Integer.compare(o2.getPriority(), o1.getPriority())); - log.info("Recursive lookup enabled: {}", cfg.isEnabled()); - for (String cidr : cfg.getAllowedCidr()) { + log.info("Recursive lookup enabled: {}", cfg.getRecursive().isEnabled()); + for (String cidr : cfg.getRecursive().getAllowedCidr()) { log.info("{} is allowed for recursion", cidr); allowedCidr.add(new CIDRUtils(cidr)); } @@ -84,7 +73,7 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy { boolean canRecurse = false; try { - if (cfg.isEnabled()) { + if (cfg.getRecursive().isEnabled()) { log.debug("Checking {} CIDRs for recursion", allowedCidr.size()); for (CIDRUtils cidr : allowedCidr) { if (cidr.isInRange(source)) { @@ -170,10 +159,10 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy { } if ( - cfg.getBridge() != null && - cfg.getBridge().getEnabled() && - (!cfg.getBridge().getRecursiveOnly() || isAllowedForRecursive(request.getRequester())) - ) { + cfg.getRecursive().getBridge() != null && + cfg.getRecursive().getBridge().getEnabled() && + (!cfg.getRecursive().getBridge().getRecursiveOnly() || isAllowedForRecursive(request.getRequester())) + ) { log.info("Using bridge failover for lookup"); Optional lookupDataOpt = bridge.find(request); log.info("Found 3PID mapping: {medium: '{}', address: '{}', mxid: '{}'}", @@ -197,7 +186,7 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy { @Override public List find(BulkLookupRequest request) { - if (!bulkCfg.getEnabled()) { + if (!cfg.getBulk().getEnabled()) { return Collections.emptyList(); } diff --git a/src/main/java/io/kamax/mxisd/notification/NotificationHandlers.java b/src/main/java/io/kamax/mxisd/notification/NotificationHandlers.java new file mode 100644 index 0000000..424ed5a --- /dev/null +++ b/src/main/java/io/kamax/mxisd/notification/NotificationHandlers.java @@ -0,0 +1,40 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.notification; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class NotificationHandlers { + + private static final List> suppliers = new ArrayList<>(); + + public static void register(Supplier supplier) { + suppliers.add(supplier); + } + + public static List get() { + return suppliers.stream().map(Supplier::get).collect(Collectors.toList()); + } + +} diff --git a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java index 075c97e..df00b3f 100644 --- a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java +++ b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java @@ -28,21 +28,17 @@ import io.kamax.mxisd.threepid.session.IThreePidSession; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.Map; -@Component public class NotificationManager { - private Logger log = LoggerFactory.getLogger(NotificationManager.class); + private transient final Logger log = LoggerFactory.getLogger(NotificationManager.class); private Map handlers; - @Autowired public NotificationManager(NotificationConfig cfg, List handlers) { this.handlers = new HashMap<>(); handlers.forEach(h -> { diff --git a/src/main/java/io/kamax/mxisd/profile/ProfileManager.java b/src/main/java/io/kamax/mxisd/profile/ProfileManager.java index 4ff143b..050ed80 100644 --- a/src/main/java/io/kamax/mxisd/profile/ProfileManager.java +++ b/src/main/java/io/kamax/mxisd/profile/ProfileManager.java @@ -20,36 +20,43 @@ package io.kamax.mxisd.profile; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import io.kamax.matrix._MatrixID; import io.kamax.matrix._ThreePid; +import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.dns.ClientDnsOverwrite; +import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.proxy.Response; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; -@Component public class ProfileManager { - private final Logger log = LoggerFactory.getLogger(ProfileManager.class); + private transient final Logger log = LoggerFactory.getLogger(ProfileManager.class); private List providers; + private ClientDnsOverwrite dns; + private CloseableHttpClient client; - @Autowired - public ProfileManager(List providers) { - this.providers = providers; - } + public ProfileManager(List providers, ClientDnsOverwrite dns, CloseableHttpClient client) { + this.dns = dns; + this.client = client; - @PostConstruct - public void build() { log.info("--- Profile providers ---"); - providers = providers.stream() + this.providers = providers.stream() .filter(pp -> { log.info("\t- {} - Is enabled? {}", pp.getClass().getSimpleName(), pp.isEnabled()); return pp.isEnabled(); @@ -84,4 +91,29 @@ public class ProfileManager { return getList(p -> p.getRoles(user)); } + public Response enhance(_MatrixID userId, HttpRequestBase request) { + try { + request.setURI(dns.transform(request.getURI()).build()); + + Response res = new Response(); + try (CloseableHttpResponse hsResponse = client.execute(request)) { + res.setStatus(hsResponse.getStatusLine().getStatusCode()); + JsonElement el = GsonUtil.parse(EntityUtils.toString(hsResponse.getEntity())); + if (el.isJsonObject()) { + JsonObject obj = el.getAsJsonObject(); + List<_ThreePid> list = getThreepids(userId); + obj.add("threepids", GsonUtil.get().toJsonTree(list)); + } + + res.setBody(GsonUtil.get().toJson(el)); + return res; + } catch (IOException e) { + throw new RuntimeException(e); + } + } catch (URISyntaxException e) { + log.error("Unable to build target URL for profile proxy enhancement", e); + throw new InternalServerError(e); + } + } + } diff --git a/src/main/java/io/kamax/mxisd/profile/ProfileProviders.java b/src/main/java/io/kamax/mxisd/profile/ProfileProviders.java new file mode 100644 index 0000000..4f01543 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/profile/ProfileProviders.java @@ -0,0 +1,40 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.profile; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class ProfileProviders { + + private static final List> providers = new ArrayList<>(); + + public static void register(Supplier supplier) { + providers.add(supplier); + } + + public static List get() { + return providers.stream().map(Supplier::get).collect(Collectors.toList()); + } + +} diff --git a/src/main/java/io/kamax/mxisd/proxy/Response.java b/src/main/java/io/kamax/mxisd/proxy/Response.java new file mode 100644 index 0000000..59f9a4c --- /dev/null +++ b/src/main/java/io/kamax/mxisd/proxy/Response.java @@ -0,0 +1,56 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2018 Kamax Sàrl + * + * 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.proxy; + +import java.util.List; +import java.util.Map; + +public class Response { + + private int status; + private Map> headers; + private String body; + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public Map> getHeaders() { + return headers; + } + + public void setHeaders(Map> headers) { + this.headers = headers; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + +} diff --git a/src/main/java/io/kamax/mxisd/session/SessionMananger.java b/src/main/java/io/kamax/mxisd/session/SessionMananger.java index 487e6b3..73e0c32 100644 --- a/src/main/java/io/kamax/mxisd/session/SessionMananger.java +++ b/src/main/java/io/kamax/mxisd/session/SessionMananger.java @@ -30,9 +30,9 @@ import io.kamax.matrix.ThreePidMedium; import io.kamax.matrix._MatrixID; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.SessionConfig; -import io.kamax.mxisd.controller.identity.v1.io.RequestTokenResponse; -import io.kamax.mxisd.controller.identity.v1.remote.RemoteIdentityAPIv1; 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.ThreePidValidation; import io.kamax.mxisd.matrix.IdentityServerUtils; import io.kamax.mxisd.notification.NotificationManager; @@ -50,12 +50,9 @@ 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.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -66,10 +63,9 @@ import java.util.Optional; import static io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate; import static io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource; -@Component public class SessionMananger { - private Logger log = LoggerFactory.getLogger(SessionMananger.class); + private transient final Logger log = LoggerFactory.getLogger(SessionMananger.class); private SessionConfig cfg; private MatrixConfig mxCfg; @@ -80,14 +76,14 @@ public class SessionMananger { private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); // FIXME refactor for sessions handling their own stuff // FIXME export into central class, set version - private CloseableHttpClient client = HttpClients.custom().setUserAgent("mxisd").build(); + private CloseableHttpClient client; - @Autowired - public SessionMananger(SessionConfig cfg, MatrixConfig mxCfg, IStorage storage, NotificationManager notifMgr) { + public SessionMananger(SessionConfig cfg, MatrixConfig mxCfg, IStorage storage, NotificationManager notifMgr, CloseableHttpClient client) { this.cfg = cfg; this.mxCfg = mxCfg; this.storage = storage; this.notifMgr = notifMgr; + this.client = client; } private boolean isLocal(ThreePid tpid) { @@ -96,7 +92,7 @@ public class SessionMananger { } String domain = tpid.getAddress().split("@")[1]; - return StringUtils.equalsIgnoreCase(cfg.getMatrixCfg().getDomain(), domain); + return StringUtils.equalsIgnoreCase(mxCfg.getDomain(), domain); } private ThreePidSession getSession(String sid, String secret) { diff --git a/src/main/java/io/kamax/mxisd/spring/CryptoFactory.java b/src/main/java/io/kamax/mxisd/spring/CryptoFactory.java index 18541b1..641b49d 100644 --- a/src/main/java/io/kamax/mxisd/spring/CryptoFactory.java +++ b/src/main/java/io/kamax/mxisd/spring/CryptoFactory.java @@ -26,17 +26,13 @@ import io.kamax.matrix.crypto.SignatureManager; import io.kamax.mxisd.config.KeyConfig; import io.kamax.mxisd.config.ServerConfig; import org.apache.commons.io.FileUtils; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import java.io.File; import java.io.IOException; -@Configuration public class CryptoFactory { - @Bean - public KeyManager getKeyManager(KeyConfig keyCfg) { + public static KeyManager getKeyManager(KeyConfig keyCfg) { File keyStore = new File(keyCfg.getPath()); if (!keyStore.exists()) { try { @@ -49,8 +45,7 @@ public class CryptoFactory { return new KeyManager(new KeyFileStore(keyCfg.getPath())); } - @Bean - public SignatureManager getSignatureManager(KeyManager keyMgr, ServerConfig cfg) { + public static SignatureManager getSignatureManager(KeyManager keyMgr, ServerConfig cfg) { return new SignatureManager(keyMgr, cfg.getName()); } diff --git a/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorage.java b/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorage.java index 25d6cab..26fef5c 100644 --- a/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorage.java +++ b/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorage.java @@ -27,6 +27,8 @@ import com.j256.ormlite.jdbc.JdbcConnectionSource; import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.table.TableUtils; import io.kamax.matrix.ThreePid; +import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.exception.ConfigurationException; import io.kamax.mxisd.exception.InternalServerError; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.storage.IStorage; @@ -34,6 +36,7 @@ import io.kamax.mxisd.storage.dao.IThreePidSessionDao; import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao; import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO; import io.kamax.mxisd.storage.ormlite.dao.ThreePidSessionDao; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +51,7 @@ import java.util.Optional; public class OrmLiteSqliteStorage implements IStorage { - private Logger log = LoggerFactory.getLogger(OrmLiteSqliteStorage.class); + private transient final Logger log = LoggerFactory.getLogger(OrmLiteSqliteStorage.class); @FunctionalInterface private interface Getter { @@ -68,7 +71,19 @@ public class OrmLiteSqliteStorage implements IStorage { private Dao sessionDao; private Dao asTxnDao; + public OrmLiteSqliteStorage(MxisdConfig cfg) { + this(cfg.getStorage().getBackend(), cfg.getStorage().getProvider().getSqlite().getDatabase()); + } + public OrmLiteSqliteStorage(String backend, String path) { + if (StringUtils.isBlank(backend)) { + throw new ConfigurationException("storage.backend"); + } + + if (StringUtils.isBlank(path)) { + throw new ConfigurationException("Storage destination cannot be empty"); + } + withCatcher(() -> { if (path.startsWith("/") && !path.startsWith("//")) { File parent = new File(path).getParentFile(); diff --git a/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorageBeanFactory.java b/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorageBeanFactory.java deleted file mode 100644 index 33ba7f3..0000000 --- a/src/main/java/io/kamax/mxisd/storage/ormlite/OrmLiteSqliteStorageBeanFactory.java +++ /dev/null @@ -1,78 +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.storage.ormlite; - -import io.kamax.mxisd.config.SQLiteStorageConfig; -import io.kamax.mxisd.config.StorageConfig; -import io.kamax.mxisd.exception.ConfigurationException; -import io.kamax.mxisd.storage.IStorage; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; - -@Component -public class OrmLiteSqliteStorageBeanFactory implements FactoryBean { - - @Autowired - private StorageConfig storagecfg; - - @Autowired - private SQLiteStorageConfig cfg; - - private OrmLiteSqliteStorage storage; - - @PostConstruct - private void postConstruct() { - if (StringUtils.isBlank(storagecfg.getBackend())) { - throw new ConfigurationException("storage.backend"); - } - - if (StringUtils.equals("sqlite", storagecfg.getBackend()) && StringUtils.isBlank(cfg.getDatabase())) { - throw new ConfigurationException("storage.provider.sqlite.database"); - } - - storage = new OrmLiteSqliteStorage(storagecfg.getBackend(), cfg.getDatabase()); - } - - @Override - public IStorage getObject() throws Exception { - if (storage == null) { - throw new FactoryBeanNotInitializedException(); - } - - return storage; - } - - @Override - public Class getObjectType() { - return OrmLiteSqliteStorage.class; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java index a7302be..7be2c0e 100644 --- a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java @@ -36,8 +36,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.io.FileInputStream; import java.io.IOException; @@ -47,15 +45,13 @@ import static com.sendgrid.SendGrid.Email; import static com.sendgrid.SendGrid.Response; import static io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig.EmailTemplate; -@Component public class EmailSendGridNotificationHandler extends PlaceholderNotificationGenerator implements INotificationHandler { - private Logger log = LoggerFactory.getLogger(EmailSendGridNotificationHandler.class); + private transient final Logger log = LoggerFactory.getLogger(EmailSendGridNotificationHandler.class); private EmailSendGridConfig cfg; private SendGrid sendgrid; - @Autowired public EmailSendGridNotificationHandler(MatrixConfig mxCfg, ServerConfig srvCfg, EmailSendGridConfig cfg) { super(mxCfg, srvCfg); this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java index 21f48fe..e7c95dd 100644 --- a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java +++ b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java @@ -29,8 +29,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import javax.mail.Message; import javax.mail.MessagingException; @@ -42,15 +40,13 @@ import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Properties; -@Component public class EmailSmtpConnector implements IEmailConnector { - private Logger log = LoggerFactory.getLogger(EmailSmtpConnector.class); + private transient final Logger log = LoggerFactory.getLogger(EmailSmtpConnector.class); private EmailSmtpConfig cfg; private Session session; - @Autowired public EmailSmtpConnector(EmailSmtpConfig cfg) { this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/phone/BlackholePhoneConnector.java b/src/main/java/io/kamax/mxisd/threepid/connector/phone/BlackholePhoneConnector.java index 6a366b3..063001b 100644 --- a/src/main/java/io/kamax/mxisd/threepid/connector/phone/BlackholePhoneConnector.java +++ b/src/main/java/io/kamax/mxisd/threepid/connector/phone/BlackholePhoneConnector.java @@ -20,9 +20,6 @@ package io.kamax.mxisd.threepid.connector.phone; -import org.springframework.stereotype.Component; - -@Component public class BlackholePhoneConnector implements IPhoneConnector { @Override diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/phone/PhoneSmsTwilioConnector.java b/src/main/java/io/kamax/mxisd/threepid/connector/phone/PhoneSmsTwilioConnector.java index 4205aae..9d2b713 100644 --- a/src/main/java/io/kamax/mxisd/threepid/connector/phone/PhoneSmsTwilioConnector.java +++ b/src/main/java/io/kamax/mxisd/threepid/connector/phone/PhoneSmsTwilioConnector.java @@ -28,17 +28,13 @@ import io.kamax.mxisd.exception.BadRequestException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class PhoneSmsTwilioConnector implements IPhoneConnector { - private Logger log = LoggerFactory.getLogger(PhoneSmsTwilioConnector.class); + private transient final Logger log = LoggerFactory.getLogger(PhoneSmsTwilioConnector.class); private PhoneTwilioConfig cfg; - @Autowired public PhoneSmsTwilioConnector(PhoneTwilioConfig cfg) { this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java index 38fd66a..2ea0057 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java @@ -27,29 +27,18 @@ import io.kamax.mxisd.config.threepid.medium.GenericTemplateConfig; import io.kamax.mxisd.exception.InternalServerError; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.threepid.session.IThreePidSession; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -@Component public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements INotificationGenerator { - private Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class); + private transient final Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class); private GenericTemplateConfig cfg; - @Autowired - private ApplicationContext app; - public GenericTemplateNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, GenericTemplateConfig cfg) { super(mxCfg, srvCfg); this.cfg = cfg; @@ -57,9 +46,13 @@ public abstract class GenericTemplateNotificationGenerator extends PlaceholderNo private String getTemplateContent(String location) { try { + // FIXME make it work again + /* InputStream is = StringUtils.startsWith(location, "classpath:") ? app.getResource(location).getInputStream() : new FileInputStream(location); return IOUtils.toString(is, StandardCharsets.UTF_8); + */ + throw new IOException("Not implemented!"); } catch (IOException e) { throw new InternalServerError("Unable to read template content at " + location + ": " + e.getMessage()); } diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java index 482c793..1bd4f71 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java @@ -24,7 +24,7 @@ import io.kamax.matrix.ThreePid; import io.kamax.mxisd.as.IMatrixIdInvite; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ServerConfig; -import io.kamax.mxisd.controller.identity.v1.IdentityAPIv1; +import io.kamax.mxisd.http.IsAPIv1; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.threepid.session.IThreePidSession; import org.apache.commons.lang.StringUtils; @@ -86,7 +86,7 @@ public abstract class PlaceholderNotificationGenerator { } protected String populateForValidation(IThreePidSession session, String input) { - String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate( + String validationLink = srvCfg.getPublicUrl() + IsAPIv1.getValidate( session.getThreePid().getMedium(), session.getId(), session.getSecret(), diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationGenerator.java index 1fafe5c..6549092 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationGenerator.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationGenerator.java @@ -26,15 +26,11 @@ 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 org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component public class EmailNotificationGenerator extends GenericTemplateNotificationGenerator implements IEmailNotificationGenerator { private EmailConfig cfg; - @Autowired public EmailNotificationGenerator(EmailTemplateConfig templateCfg, EmailConfig cfg, MatrixConfig mxCfg, ServerConfig srvCfg) { super(mxCfg, srvCfg, templateCfg); this.cfg = cfg; diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java index 53f2fb0..99aeeb1 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java @@ -24,17 +24,13 @@ 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.notification.GenericNotificationHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.List; -@Component public class EmailRawNotificationHandler extends GenericNotificationHandler { private EmailConfig cfg; - @Autowired public EmailRawNotificationHandler(EmailConfig cfg, List generators, List connectors) { this.cfg = cfg; process(connectors, generators); diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java index 1539e78..7217ec3 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java @@ -24,17 +24,13 @@ 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.notification.GenericNotificationHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.util.List; -@Component public class PhoneNotificationHandler extends GenericNotificationHandler { private PhoneConfig cfg; - @Autowired public PhoneNotificationHandler(PhoneConfig cfg, List connectors, List generators) { this.cfg = cfg; process(connectors, generators); diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/phone/SmsNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/phone/SmsNotificationGenerator.java index 99c26a4..a5d14b2 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/phone/SmsNotificationGenerator.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/phone/SmsNotificationGenerator.java @@ -24,9 +24,7 @@ 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 org.springframework.stereotype.Component; -@Component public class SmsNotificationGenerator extends GenericTemplateNotificationGenerator implements IPhoneNotificationGenerator { public SmsNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, PhoneSmsTemplateConfig cfg) { diff --git a/src/main/java/io/kamax/mxisd/util/GsonParser.java b/src/main/java/io/kamax/mxisd/util/GsonParser.java index 15100a8..b2b1f86 100644 --- a/src/main/java/io/kamax/mxisd/util/GsonParser.java +++ b/src/main/java/io/kamax/mxisd/util/GsonParser.java @@ -26,7 +26,6 @@ import io.kamax.mxisd.exception.JsonMemberNotFoundException; import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -54,10 +53,6 @@ public class GsonParser { return el.getAsJsonObject(); } - public T parse(HttpServletRequest req, Class type) throws IOException { - return gson.fromJson(parse(req.getInputStream()), type); - } - public T parse(HttpResponse res, Class type) throws IOException { return gson.fromJson(parse(res.getEntity().getContent()), type); } diff --git a/src/main/resources/META-INF/services/io.kamax.mxisd.backend.IdentityStoreSupplier b/src/main/resources/META-INF/services/io.kamax.mxisd.backend.IdentityStoreSupplier new file mode 100644 index 0000000..44c2b7e --- /dev/null +++ b/src/main/resources/META-INF/services/io.kamax.mxisd.backend.IdentityStoreSupplier @@ -0,0 +1,9 @@ +io.kamax.mxisd.backend.exec.ExecIdentityStoreSupplier +io.kamax.mxisd.backend.firebase.GoogleFirebaseStoreSupplier +io.kamax.mxisd.backend.ldap.LdapStoreSupplier +io.kamax.mxisd.backend.ldap.netiq.NetIqLdapStoreSupplier +io.kamax.mxisd.backend.memory.MemoryIdentityStoreSupplier +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 diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 2496c62..5b9ad51 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -240,8 +240,8 @@ session: server: 'matrix-org' notification: -# handler: -# 3PID-medium: 'handlerId' + # handler: + # 3PID-medium: 'handlerId' handlers: sendgrid: api: diff --git a/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html b/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html index 2dc81a1..e2b0af7 100644 --- a/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html +++ b/src/main/resources/templates/session/localRemote/tokenSubmitSuccess.html @@ -1,5 +1,5 @@ - + Matrix Token Verification @@ -37,7 +37,7 @@

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 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 diff --git a/src/test/java/io/kamax/mxisd/backend/exec/ExecDirectoryStoreTest.java b/src/test/java/io/kamax/mxisd/backend/exec/ExecDirectoryStoreTest.java index 46a2f02..edaf8e9 100644 --- a/src/test/java/io/kamax/mxisd/backend/exec/ExecDirectoryStoreTest.java +++ b/src/test/java/io/kamax/mxisd/backend/exec/ExecDirectoryStoreTest.java @@ -23,8 +23,8 @@ package io.kamax.mxisd.backend.exec; import io.kamax.matrix.MatrixID; import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.config.ExecConfig; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.exception.InternalServerError; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import org.apache.commons.lang3.StringUtils; import org.junit.Test; @@ -55,7 +55,7 @@ public class ExecDirectoryStoreTest extends ExecStoreTest { } private ExecConfig.Directory getCfg() { - ExecConfig.Directory cfg = new ExecConfig().compute().getDirectory(); + ExecConfig.Directory cfg = new ExecConfig().build().getDirectory(); assertFalse(cfg.isEnabled()); cfg.setEnabled(true); assertTrue(cfg.isEnabled()); diff --git a/src/test/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreTest.java b/src/test/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreTest.java index 16e258f..863c559 100644 --- a/src/test/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreTest.java +++ b/src/test/java/io/kamax/mxisd/backend/exec/ExecIdentityStoreTest.java @@ -61,7 +61,7 @@ public class ExecIdentityStoreTest extends ExecStoreTest { } private ExecConfig.Identity getCfg() { - ExecConfig.Identity cfg = new ExecConfig().compute().getIdentity(); + ExecConfig.Identity cfg = new ExecConfig().build().getIdentity(); assertFalse(cfg.isEnabled()); cfg.setEnabled(true); assertTrue(cfg.isEnabled()); diff --git a/src/test/java/io/kamax/mxisd/backend/exec/ExecProfileStoreTest.java b/src/test/java/io/kamax/mxisd/backend/exec/ExecProfileStoreTest.java index ee5225d..70aa776 100644 --- a/src/test/java/io/kamax/mxisd/backend/exec/ExecProfileStoreTest.java +++ b/src/test/java/io/kamax/mxisd/backend/exec/ExecProfileStoreTest.java @@ -69,7 +69,7 @@ public class ExecProfileStoreTest extends ExecStoreTest { } private ExecConfig.Profile getCfg() { - ExecConfig.Profile cfg = new ExecConfig().compute().getProfile(); + ExecConfig.Profile cfg = new ExecConfig().build().getProfile(); assertFalse(cfg.isEnabled()); cfg.setEnabled(true); assertTrue(cfg.isEnabled()); diff --git a/src/test/java/io/kamax/mxisd/backend/rest/RestDirectoryProviderTest.java b/src/test/java/io/kamax/mxisd/backend/rest/RestDirectoryProviderTest.java index f861b99..8a75f38 100644 --- a/src/test/java/io/kamax/mxisd/backend/rest/RestDirectoryProviderTest.java +++ b/src/test/java/io/kamax/mxisd/backend/rest/RestDirectoryProviderTest.java @@ -24,7 +24,7 @@ import com.github.tomakehurst.wiremock.junit.WireMockRule; import io.kamax.matrix.MatrixID; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.rest.RestBackendConfig; -import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; +import io.kamax.mxisd.http.io.UserDirectorySearchResult; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule;