Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4776b50e2 | ||
|
|
2458b38b75 | ||
|
|
249e28a8b5 | ||
|
|
ba9e2d6121 | ||
|
|
f042b82a50 | ||
|
|
59071177ad | ||
|
|
6450cd1f20 | ||
|
|
90bc244f3e | ||
|
|
6e52a509db | ||
|
|
5ca666981a |
28
build.gradle
28
build.gradle
@@ -78,7 +78,7 @@ buildscript {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
|
classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
|
||||||
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
|
classpath 'com.github.ben-manes:gradle-versions-plugin:0.21.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,12 +94,12 @@ dependencies {
|
|||||||
compile 'commons-io:commons-io:2.6'
|
compile 'commons-io:commons-io:2.6'
|
||||||
|
|
||||||
// Config management
|
// Config management
|
||||||
compile 'org.yaml:snakeyaml:1.25'
|
compile 'org.yaml:snakeyaml:1.24'
|
||||||
|
|
||||||
// Dependencies from old Matrix-java-sdk
|
// Dependencies from old Matrix-java-sdk
|
||||||
compile 'org.apache.commons:commons-lang3:3.9'
|
compile 'org.apache.commons:commons-lang3:3.9'
|
||||||
compile 'com.squareup.okhttp3:okhttp:4.2.2'
|
compile 'com.squareup.okhttp3:okhttp:4.0.1'
|
||||||
compile 'commons-codec:commons-codec:1.13'
|
compile 'commons-codec:commons-codec:1.12'
|
||||||
|
|
||||||
// ORMLite
|
// ORMLite
|
||||||
compile 'com.j256.ormlite:ormlite-jdbc:5.1'
|
compile 'com.j256.ormlite:ormlite-jdbc:5.1'
|
||||||
@@ -114,10 +114,10 @@ dependencies {
|
|||||||
compile 'dnsjava:dnsjava:2.1.9'
|
compile 'dnsjava:dnsjava:2.1.9'
|
||||||
|
|
||||||
// HTTP connections
|
// HTTP connections
|
||||||
compile 'org.apache.httpcomponents:httpclient:4.5.10'
|
compile 'org.apache.httpcomponents:httpclient:4.5.9'
|
||||||
|
|
||||||
// Phone numbers validation
|
// Phone numbers validation
|
||||||
compile 'com.googlecode.libphonenumber:libphonenumber:8.10.22'
|
compile 'com.googlecode.libphonenumber:libphonenumber:8.10.15'
|
||||||
|
|
||||||
// E-mail sending
|
// E-mail sending
|
||||||
compile 'javax.mail:javax.mail-api:1.6.2'
|
compile 'javax.mail:javax.mail-api:1.6.2'
|
||||||
@@ -133,13 +133,13 @@ dependencies {
|
|||||||
compile 'org.xerial:sqlite-jdbc:3.28.0'
|
compile 'org.xerial:sqlite-jdbc:3.28.0'
|
||||||
|
|
||||||
// PostgreSQL
|
// PostgreSQL
|
||||||
compile 'org.postgresql:postgresql:42.2.8'
|
compile 'org.postgresql:postgresql:42.2.6'
|
||||||
|
|
||||||
// MariaDB/MySQL
|
// MariaDB/MySQL
|
||||||
compile 'org.mariadb.jdbc:mariadb-java-client:2.5.1'
|
compile 'org.mariadb.jdbc:mariadb-java-client:2.4.2'
|
||||||
|
|
||||||
// Twilio SDK for SMS
|
// Twilio SDK for SMS
|
||||||
compile 'com.twilio.sdk:twilio:7.45.0'
|
compile 'com.twilio.sdk:twilio:7.40.1'
|
||||||
|
|
||||||
// SendGrid SDK to send emails from GCE
|
// SendGrid SDK to send emails from GCE
|
||||||
compile 'com.sendgrid:sendgrid-java:2.2.2'
|
compile 'com.sendgrid:sendgrid-java:2.2.2'
|
||||||
@@ -148,15 +148,15 @@ dependencies {
|
|||||||
compile 'org.zeroturnaround:zt-exec:1.11'
|
compile 'org.zeroturnaround:zt-exec:1.11'
|
||||||
|
|
||||||
// HTTP server
|
// HTTP server
|
||||||
compile 'io.undertow:undertow-core:2.0.27.Final'
|
compile 'io.undertow:undertow-core:2.0.22.Final'
|
||||||
|
|
||||||
// Command parser for AS interface
|
// Command parser for AS interface
|
||||||
implementation 'commons-cli:commons-cli:1.4'
|
implementation 'commons-cli:commons-cli:1.4'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.13-rc-1'
|
testCompile 'junit:junit:4.13-beta-3'
|
||||||
testCompile 'com.github.tomakehurst:wiremock:2.25.1'
|
testCompile 'com.github.tomakehurst:wiremock:2.24.0'
|
||||||
testCompile 'com.unboundid:unboundid-ldapsdk:4.0.12'
|
testCompile 'com.unboundid:unboundid-ldapsdk:4.0.11'
|
||||||
testCompile 'com.icegreen:greenmail:1.5.11'
|
testCompile 'com.icegreen:greenmail:1.5.10'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ session:
|
|||||||
validation:
|
validation:
|
||||||
enabled: true
|
enabled: true
|
||||||
unbind:
|
unbind:
|
||||||
notification:
|
notifications: true
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
# DO NOT COPY/PASTE AS-IS IN YOUR CONFIGURATION
|
# DO NOT COPY/PASTE AS-IS IN YOUR CONFIGURATION
|
||||||
@@ -115,7 +115,7 @@ are allowed to do in terms of 3PID sessions. The policy has a global on/off swit
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`unbind` controls warning notifications for 3PID removal.
|
`unbind` controls warning notifications for 3PID removal. Setting `notifications` for `unbind` to false will prevent unbind emails from sending.
|
||||||
|
|
||||||
### Web views
|
### Web views
|
||||||
Once a user click on a validation link, it is taken to the Identity Server validation page where the token is submitted.
|
Once a user click on a validation link, it is taken to the Identity Server validation page where the token is submitted.
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
#Thu Jul 04 22:47:59 MSK 2019
|
#Thu Jul 04 22:47:59 MSK 2019
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -20,12 +20,7 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd;
|
package io.kamax.mxisd;
|
||||||
|
|
||||||
import io.kamax.mxisd.config.MatrixConfig;
|
|
||||||
import io.kamax.mxisd.config.MxisdConfig;
|
import io.kamax.mxisd.config.MxisdConfig;
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.AuthorizationHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.CheckTermsHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.InternalInfoHandler;
|
import io.kamax.mxisd.http.undertow.handler.InternalInfoHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.OptionsHandler;
|
import io.kamax.mxisd.http.undertow.handler.OptionsHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.SaneHandler;
|
import io.kamax.mxisd.http.undertow.handler.SaneHandler;
|
||||||
@@ -36,46 +31,19 @@ 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.LoginGetHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginHandler;
|
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.auth.v1.LoginPostHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.auth.v2.AccountGetUserInfoHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.auth.v2.AccountLogoutHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.auth.v2.AccountRegisterHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.directory.v1.UserDirectorySearchHandler;
|
import io.kamax.mxisd.http.undertow.handler.directory.v1.UserDirectorySearchHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.EphemeralKeyIsValidHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.HelloHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.KeyGetHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.RegularKeyIsValidHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionStartHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionTpidBindHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionTpidGetValidatedHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionTpidUnbindHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionValidationGetHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SessionValidationPostHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.SignEd25519Handler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.StoreInviteHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.v1.*;
|
import io.kamax.mxisd.http.undertow.handler.identity.v1.*;
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.v2.HashDetailsHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.v2.HashLookupHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.invite.v1.RoomInviteHandler;
|
import io.kamax.mxisd.http.undertow.handler.invite.v1.RoomInviteHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.profile.v1.InternalProfileHandler;
|
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.profile.v1.ProfileHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.register.v1.Register3pidRequestTokenHandler;
|
import io.kamax.mxisd.http.undertow.handler.register.v1.Register3pidRequestTokenHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.status.StatusHandler;
|
import io.kamax.mxisd.http.undertow.handler.status.StatusHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.status.VersionHandler;
|
import io.kamax.mxisd.http.undertow.handler.status.VersionHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.term.v2.AcceptTermsHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.term.v2.GetTermsHandler;
|
|
||||||
import io.kamax.mxisd.matrix.IdentityServiceAPI;
|
|
||||||
import io.undertow.Handlers;
|
import io.undertow.Handlers;
|
||||||
import io.undertow.Undertow;
|
import io.undertow.Undertow;
|
||||||
import io.undertow.server.HttpHandler;
|
import io.undertow.server.HttpHandler;
|
||||||
import io.undertow.server.RoutingHandler;
|
|
||||||
import io.undertow.util.HttpString;
|
|
||||||
import io.undertow.util.Methods;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class HttpMxisd {
|
public class HttpMxisd {
|
||||||
|
|
||||||
@@ -98,11 +66,16 @@ public class HttpMxisd {
|
|||||||
public void start() {
|
public void start() {
|
||||||
m.start();
|
m.start();
|
||||||
|
|
||||||
|
HttpHandler helloHandler = SaneHandler.around(new HelloHandler());
|
||||||
|
|
||||||
HttpHandler asUserHandler = SaneHandler.around(new AsUserHandler(m.getAs()));
|
HttpHandler asUserHandler = SaneHandler.around(new AsUserHandler(m.getAs()));
|
||||||
HttpHandler asTxnHandler = SaneHandler.around(new AsTransactionHandler(m.getAs()));
|
HttpHandler asTxnHandler = SaneHandler.around(new AsTransactionHandler(m.getAs()));
|
||||||
HttpHandler asNotFoundHandler = SaneHandler.around(new AsNotFoundHandler(m.getAs()));
|
HttpHandler asNotFoundHandler = SaneHandler.around(new AsNotFoundHandler(m.getAs()));
|
||||||
|
|
||||||
final RoutingHandler handler = Handlers.routing()
|
HttpHandler storeInvHandler = SaneHandler.around(new StoreInviteHandler(m.getConfig().getServer(), m.getInvite(), m.getKeyManager()));
|
||||||
|
|
||||||
|
httpSrv = Undertow.builder().addHttpListener(m.getConfig().getServer().getPort(), "0.0.0.0").setHandler(Handlers.routing()
|
||||||
|
|
||||||
.add("OPTIONS", "/**", SaneHandler.around(new OptionsHandler()))
|
.add("OPTIONS", "/**", SaneHandler.around(new OptionsHandler()))
|
||||||
|
|
||||||
// Status endpoints
|
// Status endpoints
|
||||||
@@ -114,23 +87,34 @@ public class HttpMxisd {
|
|||||||
.post(LoginHandler.Path, SaneHandler.around(new LoginPostHandler(m.getAuth())))
|
.post(LoginHandler.Path, SaneHandler.around(new LoginPostHandler(m.getAuth())))
|
||||||
.post(RestAuthHandler.Path, SaneHandler.around(new RestAuthHandler(m.getAuth())))
|
.post(RestAuthHandler.Path, SaneHandler.around(new RestAuthHandler(m.getAuth())))
|
||||||
|
|
||||||
// Account endpoints
|
|
||||||
.post(AccountRegisterHandler.Path, SaneHandler.around(new AccountRegisterHandler(m.getAccMgr())))
|
|
||||||
.get(AccountGetUserInfoHandler.Path,
|
|
||||||
SaneHandler.around(AuthorizationHandler.around(m.getAccMgr(), new AccountGetUserInfoHandler(m.getAccMgr()))))
|
|
||||||
.post(AccountLogoutHandler.Path,
|
|
||||||
SaneHandler.around(AuthorizationHandler.around(m.getAccMgr(), new AccountLogoutHandler(m.getAccMgr()))))
|
|
||||||
|
|
||||||
// Directory endpoints
|
// Directory endpoints
|
||||||
.post(UserDirectorySearchHandler.Path, SaneHandler.around(new UserDirectorySearchHandler(m.getDirectory())))
|
.post(UserDirectorySearchHandler.Path, SaneHandler.around(new UserDirectorySearchHandler(m.getDirectory())))
|
||||||
|
|
||||||
|
// Key endpoints
|
||||||
|
.get(KeyGetHandler.Path, SaneHandler.around(new KeyGetHandler(m.getKeyManager())))
|
||||||
|
.get(RegularKeyIsValidHandler.Path, SaneHandler.around(new RegularKeyIsValidHandler(m.getKeyManager())))
|
||||||
|
.get(EphemeralKeyIsValidHandler.Path, SaneHandler.around(new EphemeralKeyIsValidHandler(m.getKeyManager())))
|
||||||
|
|
||||||
|
// Identity endpoints
|
||||||
|
.get(HelloHandler.Path, helloHandler)
|
||||||
|
.get(HelloHandler.Path + "/", helloHandler) // Be lax with possibly trailing slash
|
||||||
|
.get(SingleLookupHandler.Path, SaneHandler.around(new SingleLookupHandler(m.getConfig(), m.getIdentity(), m.getSign())))
|
||||||
|
.post(BulkLookupHandler.Path, SaneHandler.around(new BulkLookupHandler(m.getIdentity())))
|
||||||
|
.post(StoreInviteHandler.Path, storeInvHandler)
|
||||||
|
.post(SessionStartHandler.Path, SaneHandler.around(new SessionStartHandler(m.getSession())))
|
||||||
|
.get(SessionValidateHandler.Path, SaneHandler.around(new SessionValidationGetHandler(m.getSession(), m.getConfig())))
|
||||||
|
.post(SessionValidateHandler.Path, SaneHandler.around(new SessionValidationPostHandler(m.getSession())))
|
||||||
|
.get(SessionTpidGetValidatedHandler.Path, SaneHandler.around(new SessionTpidGetValidatedHandler(m.getSession())))
|
||||||
|
.post(SessionTpidBindHandler.Path, SaneHandler.around(new SessionTpidBindHandler(m.getSession(), m.getInvite(), m.getSign())))
|
||||||
|
.post(SessionTpidUnbindHandler.Path, SaneHandler.around(new SessionTpidUnbindHandler(m.getSession())))
|
||||||
|
.post(SignEd25519Handler.Path, SaneHandler.around(new SignEd25519Handler(m.getConfig(), m.getInvite(), m.getSign())))
|
||||||
|
|
||||||
// Profile endpoints
|
// Profile endpoints
|
||||||
.get(ProfileHandler.Path, SaneHandler.around(new ProfileHandler(m.getProfile())))
|
.get(ProfileHandler.Path, SaneHandler.around(new ProfileHandler(m.getProfile())))
|
||||||
.get(InternalProfileHandler.Path, SaneHandler.around(new InternalProfileHandler(m.getProfile())))
|
.get(InternalProfileHandler.Path, SaneHandler.around(new InternalProfileHandler(m.getProfile())))
|
||||||
|
|
||||||
// Registration endpoints
|
// Registration endpoints
|
||||||
.post(Register3pidRequestTokenHandler.Path,
|
.post(Register3pidRequestTokenHandler.Path, SaneHandler.around(new Register3pidRequestTokenHandler(m.getReg(), m.getClientDns(), m.getHttpClient())))
|
||||||
SaneHandler.around(new Register3pidRequestTokenHandler(m.getReg(), m.getClientDns(), m.getHttpClient())))
|
|
||||||
|
|
||||||
// Invite endpoints
|
// Invite endpoints
|
||||||
.post(RoomInviteHandler.Path, SaneHandler.around(new RoomInviteHandler(m.getHttpClient(), m.getClientDns(), m.getInvite())))
|
.post(RoomInviteHandler.Path, SaneHandler.around(new RoomInviteHandler(m.getHttpClient(), m.getClientDns(), m.getInvite())))
|
||||||
@@ -145,103 +129,18 @@ public class HttpMxisd {
|
|||||||
.put("/transactions/{" + AsTransactionHandler.ID + "}", asTxnHandler) // Legacy endpoint
|
.put("/transactions/{" + AsTransactionHandler.ID + "}", asTxnHandler) // Legacy endpoint
|
||||||
|
|
||||||
// Banned endpoints
|
// Banned endpoints
|
||||||
.get(InternalInfoHandler.Path, SaneHandler.around(new InternalInfoHandler()));
|
.get(InternalInfoHandler.Path, SaneHandler.around(new InternalInfoHandler()))
|
||||||
keyEndpoints(handler);
|
|
||||||
identityEndpoints(handler);
|
).build();
|
||||||
termsEndpoints(handler);
|
|
||||||
hashEndpoints(handler);
|
|
||||||
httpSrv = Undertow.builder().addHttpListener(m.getConfig().getServer().getPort(), "0.0.0.0").setHandler(handler).build();
|
|
||||||
|
|
||||||
httpSrv.start();
|
httpSrv.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
// Because it might have never been initialized if an exception is thrown early
|
// Because it might have never been initialized if an exception is thrown early
|
||||||
if (Objects.nonNull(httpSrv)) {
|
if (Objects.nonNull(httpSrv)) httpSrv.stop();
|
||||||
httpSrv.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m.stop();
|
m.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void keyEndpoints(RoutingHandler routingHandler) {
|
|
||||||
addEndpoints(routingHandler, Methods.GET, false,
|
|
||||||
new KeyGetHandler(m.getKeyManager()),
|
|
||||||
new RegularKeyIsValidHandler(m.getKeyManager()),
|
|
||||||
new EphemeralKeyIsValidHandler(m.getKeyManager())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void identityEndpoints(RoutingHandler routingHandler) {
|
|
||||||
// Legacy v1
|
|
||||||
routingHandler.get(SingleLookupHandler.Path, sane(new SingleLookupHandler(m.getConfig(), m.getIdentity(), m.getSign())));
|
|
||||||
routingHandler.post(BulkLookupHandler.Path, sane(new BulkLookupHandler(m.getIdentity())));
|
|
||||||
|
|
||||||
addEndpoints(routingHandler, Methods.GET, false, new HelloHandler());
|
|
||||||
|
|
||||||
addEndpoints(routingHandler, Methods.GET, true,
|
|
||||||
new SessionValidationGetHandler(m.getSession(), m.getConfig()),
|
|
||||||
new SessionTpidGetValidatedHandler(m.getSession())
|
|
||||||
);
|
|
||||||
addEndpoints(routingHandler, Methods.POST, true,
|
|
||||||
new StoreInviteHandler(m.getConfig().getServer(), m.getInvite(), m.getKeyManager()),
|
|
||||||
new SessionStartHandler(m.getSession()),
|
|
||||||
new SessionValidationPostHandler(m.getSession()),
|
|
||||||
new SessionTpidBindHandler(m.getSession(), m.getInvite(), m.getSign()),
|
|
||||||
new SessionTpidUnbindHandler(m.getSession()),
|
|
||||||
new SignEd25519Handler(m.getConfig(), m.getInvite(), m.getSign())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void termsEndpoints(RoutingHandler routingHandler) {
|
|
||||||
routingHandler.get(GetTermsHandler.PATH, new GetTermsHandler(m.getConfig().getPolicy()));
|
|
||||||
routingHandler
|
|
||||||
.post(AcceptTermsHandler.PATH, AuthorizationHandler.around(m.getAccMgr(), sane(new AcceptTermsHandler(m.getAccMgr()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hashEndpoints(RoutingHandler routingHandler) {
|
|
||||||
routingHandler
|
|
||||||
.get(HashDetailsHandler.PATH, AuthorizationHandler.around(m.getAccMgr(), sane(new HashDetailsHandler(m.getHashManager()))));
|
|
||||||
routingHandler.post(HashLookupHandler.Path,
|
|
||||||
AuthorizationHandler.around(m.getAccMgr(), sane(new HashLookupHandler(m.getIdentity(), m.getHashManager()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addEndpoints(RoutingHandler routingHandler, HttpString method, boolean useAuthorization, ApiHandler... handlers) {
|
|
||||||
for (ApiHandler handler : handlers) {
|
|
||||||
attachHandler(routingHandler, method, handler, useAuthorization, sane(handler));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void attachHandler(RoutingHandler routingHandler, HttpString method, ApiHandler apiHandler, boolean useAuthorization,
|
|
||||||
HttpHandler httpHandler) {
|
|
||||||
MatrixConfig matrixConfig = m.getConfig().getMatrix();
|
|
||||||
if (matrixConfig.isV1()) {
|
|
||||||
routingHandler.add(method, apiHandler.getPath(IdentityServiceAPI.V1), httpHandler);
|
|
||||||
}
|
|
||||||
if (matrixConfig.isV2()) {
|
|
||||||
HttpHandler handlerWithTerms = CheckTermsHandler.around(m.getAccMgr(), httpHandler, getPolicyObjects(apiHandler));
|
|
||||||
HttpHandler wrappedHandler = useAuthorization ? AuthorizationHandler.around(m.getAccMgr(), handlerWithTerms) : handlerWithTerms;
|
|
||||||
routingHandler.add(method, apiHandler.getPath(IdentityServiceAPI.V2), wrappedHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<PolicyConfig.PolicyObject> getPolicyObjects(ApiHandler apiHandler) {
|
|
||||||
PolicyConfig policyConfig = m.getConfig().getPolicy();
|
|
||||||
List<PolicyConfig.PolicyObject> policies = new ArrayList<>();
|
|
||||||
if (!policyConfig.getPolicies().isEmpty()) {
|
|
||||||
for (PolicyConfig.PolicyObject policy : policyConfig.getPolicies().values()) {
|
|
||||||
for (Pattern pattern : policy.getPatterns()) {
|
|
||||||
if (pattern.matcher(apiHandler.getHandlerPath()).matches()) {
|
|
||||||
policies.add(policy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return policies;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHandler sane(HttpHandler httpHandler) {
|
|
||||||
return SaneHandler.around(httpHandler);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
package io.kamax.mxisd;
|
package io.kamax.mxisd;
|
||||||
|
|
||||||
import io.kamax.mxisd.as.AppSvcManager;
|
import io.kamax.mxisd.as.AppSvcManager;
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.auth.AuthManager;
|
import io.kamax.mxisd.auth.AuthManager;
|
||||||
import io.kamax.mxisd.auth.AuthProviders;
|
import io.kamax.mxisd.auth.AuthProviders;
|
||||||
import io.kamax.mxisd.backend.IdentityStoreSupplier;
|
import io.kamax.mxisd.backend.IdentityStoreSupplier;
|
||||||
@@ -35,7 +34,6 @@ import io.kamax.mxisd.directory.DirectoryManager;
|
|||||||
import io.kamax.mxisd.directory.DirectoryProviders;
|
import io.kamax.mxisd.directory.DirectoryProviders;
|
||||||
import io.kamax.mxisd.dns.ClientDnsOverwrite;
|
import io.kamax.mxisd.dns.ClientDnsOverwrite;
|
||||||
import io.kamax.mxisd.dns.FederationDnsOverwrite;
|
import io.kamax.mxisd.dns.FederationDnsOverwrite;
|
||||||
import io.kamax.mxisd.hash.HashManager;
|
|
||||||
import io.kamax.mxisd.invitation.InvitationManager;
|
import io.kamax.mxisd.invitation.InvitationManager;
|
||||||
import io.kamax.mxisd.lookup.ThreePidProviders;
|
import io.kamax.mxisd.lookup.ThreePidProviders;
|
||||||
import io.kamax.mxisd.lookup.fetcher.IRemoteIdentityServerFetcher;
|
import io.kamax.mxisd.lookup.fetcher.IRemoteIdentityServerFetcher;
|
||||||
@@ -87,8 +85,6 @@ public class Mxisd {
|
|||||||
private SessionManager sessMgr;
|
private SessionManager sessMgr;
|
||||||
private NotificationManager notifMgr;
|
private NotificationManager notifMgr;
|
||||||
private RegistrationManager regMgr;
|
private RegistrationManager regMgr;
|
||||||
private AccountManager accMgr;
|
|
||||||
private HashManager hashManager;
|
|
||||||
|
|
||||||
// HS-specific classes
|
// HS-specific classes
|
||||||
private Synapse synapse;
|
private Synapse synapse;
|
||||||
@@ -119,10 +115,7 @@ public class Mxisd {
|
|||||||
ServiceLoader.load(IdentityStoreSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
|
ServiceLoader.load(IdentityStoreSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
|
||||||
ServiceLoader.load(NotificationHandlerSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
|
ServiceLoader.load(NotificationHandlerSupplier.class).iterator().forEachRemaining(p -> p.accept(this));
|
||||||
|
|
||||||
hashManager = new HashManager();
|
idStrategy = new RecursivePriorityLookupStrategy(cfg.getLookup(), ThreePidProviders.get(), bridgeFetcher);
|
||||||
hashManager.init(cfg.getHashing(), ThreePidProviders.get(), store);
|
|
||||||
|
|
||||||
idStrategy = new RecursivePriorityLookupStrategy(cfg.getLookup(), ThreePidProviders.get(), bridgeFetcher, hashManager);
|
|
||||||
pMgr = new ProfileManager(ProfileProviders.get(), clientDns, httpClient);
|
pMgr = new ProfileManager(ProfileProviders.get(), clientDns, httpClient);
|
||||||
notifMgr = new NotificationManager(cfg.getNotification(), NotificationHandlers.get());
|
notifMgr = new NotificationManager(cfg.getNotification(), NotificationHandlers.get());
|
||||||
sessMgr = new SessionManager(cfg, store, notifMgr, resolver, httpClient, signMgr);
|
sessMgr = new SessionManager(cfg, store, notifMgr, resolver, httpClient, signMgr);
|
||||||
@@ -131,7 +124,6 @@ public class Mxisd {
|
|||||||
dirMgr = new DirectoryManager(cfg.getDirectory(), clientDns, httpClient, DirectoryProviders.get());
|
dirMgr = new DirectoryManager(cfg.getDirectory(), clientDns, httpClient, DirectoryProviders.get());
|
||||||
regMgr = new RegistrationManager(cfg.getRegister(), httpClient, clientDns, invMgr);
|
regMgr = new RegistrationManager(cfg.getRegister(), httpClient, clientDns, invMgr);
|
||||||
asHander = new AppSvcManager(this);
|
asHander = new AppSvcManager(this);
|
||||||
accMgr = new AccountManager(store, resolver, getHttpClient(), cfg.getAccountConfig(), cfg.getMatrix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MxisdConfig getConfig() {
|
public MxisdConfig getConfig() {
|
||||||
@@ -202,14 +194,6 @@ public class Mxisd {
|
|||||||
return synapse;
|
return synapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountManager getAccMgr() {
|
|
||||||
return accMgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashManager getHashManager() {
|
|
||||||
return hashManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
build();
|
build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,160 +0,0 @@
|
|||||||
package io.kamax.mxisd.auth;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import io.kamax.matrix.MatrixID;
|
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
|
||||||
import io.kamax.mxisd.config.AccountConfig;
|
|
||||||
import io.kamax.mxisd.config.MatrixConfig;
|
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.exception.BadRequestException;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.exception.NotFoundException;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.auth.v1.LoginGetHandler;
|
|
||||||
import io.kamax.mxisd.matrix.HomeserverFederationResolver;
|
|
||||||
import io.kamax.mxisd.storage.IStorage;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class AccountManager {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AccountManager.class);
|
|
||||||
|
|
||||||
private final IStorage storage;
|
|
||||||
private final HomeserverFederationResolver resolver;
|
|
||||||
private final CloseableHttpClient httpClient;
|
|
||||||
private final AccountConfig accountConfig;
|
|
||||||
private final MatrixConfig matrixConfig;
|
|
||||||
|
|
||||||
public AccountManager(IStorage storage, HomeserverFederationResolver resolver,
|
|
||||||
CloseableHttpClient httpClient, AccountConfig accountConfig, MatrixConfig matrixConfig) {
|
|
||||||
this.storage = storage;
|
|
||||||
this.resolver = resolver;
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.accountConfig = accountConfig;
|
|
||||||
this.matrixConfig = matrixConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String register(OpenIdToken openIdToken) {
|
|
||||||
Objects.requireNonNull(openIdToken.getAccessToken(), "Missing required access_token");
|
|
||||||
Objects.requireNonNull(openIdToken.getTokenType(), "Missing required token type");
|
|
||||||
Objects.requireNonNull(openIdToken.getMatrixServerName(), "Missing required matrix domain");
|
|
||||||
|
|
||||||
LOGGER.info("Registration from the server: {}", openIdToken.getMatrixServerName());
|
|
||||||
String userId = getUserId(openIdToken);
|
|
||||||
LOGGER.info("UserId: {}", userId);
|
|
||||||
|
|
||||||
String token = UUID.randomUUID().toString();
|
|
||||||
AccountDao account = new AccountDao(openIdToken.getAccessToken(), openIdToken.getTokenType(),
|
|
||||||
openIdToken.getMatrixServerName(), openIdToken.getExpiredIn(),
|
|
||||||
Instant.now().getEpochSecond(), userId, token);
|
|
||||||
storage.insertToken(account);
|
|
||||||
|
|
||||||
LOGGER.info("User {} registered", userId);
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getUserId(OpenIdToken openIdToken) {
|
|
||||||
String homeserverURL = resolver.resolve(openIdToken.getMatrixServerName()).toString();
|
|
||||||
LOGGER.info("Domain resolved: {} => {}", openIdToken.getMatrixServerName(), homeserverURL);
|
|
||||||
HttpGet getUserInfo = new HttpGet(
|
|
||||||
homeserverURL + "/_matrix/federation/v1/openid/userinfo?access_token=" + openIdToken.getAccessToken());
|
|
||||||
String userId;
|
|
||||||
try (CloseableHttpResponse response = httpClient.execute(getUserInfo)) {
|
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
|
||||||
if (statusCode == HttpStatus.SC_OK) {
|
|
||||||
String content = EntityUtils.toString(response.getEntity());
|
|
||||||
LOGGER.trace("Response: {}", content);
|
|
||||||
JsonObject body = GsonUtil.parseObj(content);
|
|
||||||
userId = GsonUtil.getStringOrThrow(body, "sub");
|
|
||||||
} else {
|
|
||||||
LOGGER.error("Wrong response status: {}", statusCode);
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("Unable to get user info.", e);
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
checkMXID(userId);
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkMXID(String userId) {
|
|
||||||
MatrixID mxid;
|
|
||||||
try {
|
|
||||||
mxid = MatrixID.asValid(userId);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
LOGGER.error("Wrong MXID: " + userId, e);
|
|
||||||
throw new BadRequestException("Wrong MXID");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getAccountConfig().isAllowOnlyTrustDomains()) {
|
|
||||||
LOGGER.info("Allow registration only for trust domain.");
|
|
||||||
if (getMatrixConfig().getDomain().equals(mxid.getDomain())) {
|
|
||||||
LOGGER.info("Allow user {} to registration", userId);
|
|
||||||
} else {
|
|
||||||
LOGGER.error("Deny user {} to registration", userId);
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGGER.info("Allow registration from any server.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId(String token) {
|
|
||||||
return storage.findAccount(token).orElseThrow(NotFoundException::new).getUserId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountDao findAccount(String token) {
|
|
||||||
AccountDao accountDao = storage.findAccount(token).orElse(null);
|
|
||||||
|
|
||||||
if (LOGGER.isInfoEnabled()) {
|
|
||||||
if (accountDao != null) {
|
|
||||||
LOGGER.info("Found account for user: {}", accountDao.getUserId());
|
|
||||||
} else {
|
|
||||||
LOGGER.warn("Account not found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accountDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void logout(String token) {
|
|
||||||
String userId = storage.findAccount(token).orElseThrow(InvalidCredentialsException::new).getUserId();
|
|
||||||
LOGGER.info("Logout: {}", userId);
|
|
||||||
deleteAccount(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteAccount(String token) {
|
|
||||||
storage.deleteAccepts(token);
|
|
||||||
storage.deleteToken(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void acceptTerm(String token, String url) {
|
|
||||||
storage.acceptTerm(token, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies) {
|
|
||||||
return policies.isEmpty() || storage.isTermAccepted(token, policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountConfig getAccountConfig() {
|
|
||||||
return accountConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatrixConfig getMatrixConfig() {
|
|
||||||
return matrixConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -140,7 +140,7 @@ public class AuthManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MatrixID.asValid(mxId);
|
MatrixID.asAcceptable(mxId);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
log.warn("The returned User ID {} is not a valid Matrix ID. Login might fail at the Homeserver level", mxId);
|
log.warn("The returned User ID {} is not a valid Matrix ID. Login might fail at the Homeserver level", mxId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package io.kamax.mxisd.auth;
|
|
||||||
|
|
||||||
public class OpenIdToken {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
private String tokenType;
|
|
||||||
|
|
||||||
private String matrixServerName;
|
|
||||||
|
|
||||||
private long expiredIn;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTokenType() {
|
|
||||||
return tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTokenType(String tokenType) {
|
|
||||||
this.tokenType = tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMatrixServerName() {
|
|
||||||
return matrixServerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMatrixServerName(String matrixServerName) {
|
|
||||||
this.matrixServerName = matrixServerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getExpiredIn() {
|
|
||||||
return expiredIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpiredIn(long expiredIn) {
|
|
||||||
this.expiredIn = expiredIn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -164,26 +164,6 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
|||||||
return input.toString();
|
return input.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
addBulkSuccessMapper(p);
|
|
||||||
|
|
||||||
p.withFailureDefault(output -> Collections.emptyList());
|
|
||||||
|
|
||||||
return p.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<ThreePidMapping> populateHashes() {
|
|
||||||
Processor<List<ThreePidMapping>> p = new Processor<>();
|
|
||||||
p.withConfig(cfg.getLookup().getBulk());
|
|
||||||
|
|
||||||
addBulkSuccessMapper(p);
|
|
||||||
|
|
||||||
p.withFailureDefault(output -> Collections.emptyList());
|
|
||||||
|
|
||||||
return p.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBulkSuccessMapper(Processor<List<ThreePidMapping>> p) {
|
|
||||||
p.addSuccessMapper(JsonType, output -> {
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
if (StringUtils.isBlank(output)) {
|
if (StringUtils.isBlank(output)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -208,5 +188,10 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
|||||||
throw new InternalServerError("Invalid user type: " + item.getId().getType());
|
throw new InternalServerError("Invalid user type: " + item.getId().getType());
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
p.withFailureDefault(output -> Collections.emptyList());
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class MemoryIdentityStore implements AuthenticatorProvider, DirectoryProvider, IThreePidProvider, ProfileProvider {
|
public class MemoryIdentityStore implements AuthenticatorProvider, DirectoryProvider, IThreePidProvider, ProfileProvider {
|
||||||
|
|
||||||
@@ -172,11 +171,4 @@ public class MemoryIdentityStore implements AuthenticatorProvider, DirectoryProv
|
|||||||
}).orElseGet(BackendAuthResult::failure);
|
}).orElseGet(BackendAuthResult::failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<ThreePidMapping> populateHashes() {
|
|
||||||
return cfg.getIdentities().stream()
|
|
||||||
.map(mic -> mic.getThreepids().stream().map(mtp -> new ThreePidMapping(mtp.getMedium(), mtp.getAddress(), mic.getUsername())))
|
|
||||||
.flatMap(s -> s).collect(
|
|
||||||
Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -105,27 +104,4 @@ public abstract class SqlThreePidProvider implements IThreePidProvider {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<ThreePidMapping> populateHashes() {
|
|
||||||
if (StringUtils.isBlank(cfg.getLookup().getQuery())) {
|
|
||||||
log.warn("Lookup query not configured, skip.");
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ThreePidMapping> result = new ArrayList<>();
|
|
||||||
try (Connection connection = pool.get()) {
|
|
||||||
PreparedStatement statement = connection.prepareStatement(cfg.getLookup().getQuery());
|
|
||||||
try (ResultSet resultSet = statement.executeQuery()) {
|
|
||||||
while (resultSet.next()) {
|
|
||||||
String mxid = resultSet.getString("mxid");
|
|
||||||
String medium = resultSet.getString("medium");
|
|
||||||
String address = resultSet.getString("address");
|
|
||||||
result.add(new ThreePidMapping(medium, address, mxid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.kamax.mxisd.config;
|
|
||||||
|
|
||||||
public enum AcceptingPolicy {
|
|
||||||
|
|
||||||
ALL,
|
|
||||||
|
|
||||||
ANY
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package io.kamax.mxisd.config;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class AccountConfig {
|
|
||||||
|
|
||||||
private final static Logger log = LoggerFactory.getLogger(DirectoryConfig.class);
|
|
||||||
|
|
||||||
private boolean allowOnlyTrustDomains = true;
|
|
||||||
|
|
||||||
public boolean isAllowOnlyTrustDomains() {
|
|
||||||
return allowOnlyTrustDomains;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllowOnlyTrustDomains(boolean allowOnlyTrustDomains) {
|
|
||||||
this.allowOnlyTrustDomains = allowOnlyTrustDomains;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void build() {
|
|
||||||
log.info("--- Account config ---");
|
|
||||||
log.info("Allow registration only for trust domain: {}", isAllowOnlyTrustDomains());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package io.kamax.mxisd.config;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HashingConfig {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HashingConfig.class);
|
|
||||||
|
|
||||||
private boolean enabled = false;
|
|
||||||
private int pepperLength = 10;
|
|
||||||
private RotationPolicyEnum rotationPolicy;
|
|
||||||
private HashStorageEnum hashStorageType;
|
|
||||||
private long delay = 10;
|
|
||||||
private List<Algorithm> algorithms = new ArrayList<>();
|
|
||||||
|
|
||||||
public void build() {
|
|
||||||
if (isEnabled()) {
|
|
||||||
LOGGER.info("--- Hash configuration ---");
|
|
||||||
LOGGER.info(" Pepper length: {}", getPepperLength());
|
|
||||||
LOGGER.info(" Rotation policy: {}", getRotationPolicy());
|
|
||||||
LOGGER.info(" Hash storage type: {}", getHashStorageType());
|
|
||||||
if (RotationPolicyEnum.PER_SECONDS == rotationPolicy) {
|
|
||||||
LOGGER.info(" Rotation delay: {}", delay);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGGER.info("Hash configuration disabled, used only `none` pepper.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Algorithm {
|
|
||||||
NONE,
|
|
||||||
SHA256
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum RotationPolicyEnum {
|
|
||||||
PER_REQUESTS,
|
|
||||||
PER_SECONDS
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HashStorageEnum {
|
|
||||||
IN_MEMORY,
|
|
||||||
SQL
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPepperLength() {
|
|
||||||
return pepperLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPepperLength(int pepperLength) {
|
|
||||||
this.pepperLength = pepperLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RotationPolicyEnum getRotationPolicy() {
|
|
||||||
return rotationPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRotationPolicy(RotationPolicyEnum rotationPolicy) {
|
|
||||||
this.rotationPolicy = rotationPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashStorageEnum getHashStorageType() {
|
|
||||||
return hashStorageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHashStorageType(HashStorageEnum hashStorageType) {
|
|
||||||
this.hashStorageType = hashStorageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDelay() {
|
|
||||||
return delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelay(long delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Algorithm> getAlgorithms() {
|
|
||||||
return algorithms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlgorithms(List<Algorithm> algorithms) {
|
|
||||||
this.algorithms = algorithms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -63,8 +63,6 @@ public class MatrixConfig {
|
|||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
private Identity identity = new Identity();
|
private Identity identity = new Identity();
|
||||||
private boolean v1 = true;
|
|
||||||
private boolean v2 = true;
|
|
||||||
|
|
||||||
public String getDomain() {
|
public String getDomain() {
|
||||||
return domain;
|
return domain;
|
||||||
@@ -82,22 +80,6 @@ public class MatrixConfig {
|
|||||||
this.identity = identity;
|
this.identity = identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isV1() {
|
|
||||||
return v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setV1(boolean v1) {
|
|
||||||
this.v1 = v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isV2() {
|
|
||||||
return v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setV2(boolean v2) {
|
|
||||||
this.v2 = v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void build() {
|
public void build() {
|
||||||
log.info("--- Matrix config ---");
|
log.info("--- Matrix config ---");
|
||||||
|
|
||||||
@@ -108,11 +90,6 @@ public class MatrixConfig {
|
|||||||
log.info("Domain: {}", getDomain());
|
log.info("Domain: {}", getDomain());
|
||||||
log.info("Identity:");
|
log.info("Identity:");
|
||||||
log.info("\tServers: {}", GsonUtil.get().toJson(identity.getServers()));
|
log.info("\tServers: {}", GsonUtil.get().toJson(identity.getServers()));
|
||||||
log.info("API v1: {}", v1);
|
|
||||||
log.info("API v2: {}", v2);
|
|
||||||
if (v1) {
|
|
||||||
log.warn("API v1 is deprecated via MSC2140: https://github.com/matrix-org/matrix-doc/pull/2140 and will be deleted in future releases.");
|
|
||||||
log.warn("Please upgrade your homeserver and enable only API v2.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ public class MxisdConfig {
|
|||||||
private AppServiceConfig appsvc = new AppServiceConfig();
|
private AppServiceConfig appsvc = new AppServiceConfig();
|
||||||
private AuthenticationConfig auth = new AuthenticationConfig();
|
private AuthenticationConfig auth = new AuthenticationConfig();
|
||||||
private DirectoryConfig directory = new DirectoryConfig();
|
private DirectoryConfig directory = new DirectoryConfig();
|
||||||
private AccountConfig accountConfig = new AccountConfig();
|
|
||||||
private Dns dns = new Dns();
|
private Dns dns = new Dns();
|
||||||
private ExecConfig exec = new ExecConfig();
|
private ExecConfig exec = new ExecConfig();
|
||||||
private FirebaseConfig firebase = new FirebaseConfig();
|
private FirebaseConfig firebase = new FirebaseConfig();
|
||||||
@@ -115,8 +114,6 @@ public class MxisdConfig {
|
|||||||
private ThreePidConfig threepid = new ThreePidConfig();
|
private ThreePidConfig threepid = new ThreePidConfig();
|
||||||
private ViewConfig view = new ViewConfig();
|
private ViewConfig view = new ViewConfig();
|
||||||
private WordpressConfig wordpress = new WordpressConfig();
|
private WordpressConfig wordpress = new WordpressConfig();
|
||||||
private PolicyConfig policy = new PolicyConfig();
|
|
||||||
private HashingConfig hashing = new HashingConfig();
|
|
||||||
|
|
||||||
public AppServiceConfig getAppsvc() {
|
public AppServiceConfig getAppsvc() {
|
||||||
return appsvc;
|
return appsvc;
|
||||||
@@ -134,14 +131,6 @@ public class MxisdConfig {
|
|||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountConfig getAccountConfig() {
|
|
||||||
return accountConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccountConfig(AccountConfig accountConfig) {
|
|
||||||
this.accountConfig = accountConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DirectoryConfig getDirectory() {
|
public DirectoryConfig getDirectory() {
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
@@ -326,22 +315,6 @@ public class MxisdConfig {
|
|||||||
this.wordpress = wordpress;
|
this.wordpress = wordpress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PolicyConfig getPolicy() {
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPolicy(PolicyConfig policy) {
|
|
||||||
this.policy = policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashingConfig getHashing() {
|
|
||||||
return hashing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHashing(HashingConfig hashing) {
|
|
||||||
this.hashing = hashing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MxisdConfig inMemory() {
|
public MxisdConfig inMemory() {
|
||||||
getKey().setPath(":memory:");
|
getKey().setPath(":memory:");
|
||||||
getStorage().getProvider().getSqlite().setDatabase(":memory:");
|
getStorage().getProvider().getSqlite().setDatabase(":memory:");
|
||||||
@@ -357,7 +330,6 @@ public class MxisdConfig {
|
|||||||
|
|
||||||
getAppsvc().build();
|
getAppsvc().build();
|
||||||
getAuth().build();
|
getAuth().build();
|
||||||
getAccountConfig().build();
|
|
||||||
getDirectory().build();
|
getDirectory().build();
|
||||||
getExec().build();
|
getExec().build();
|
||||||
getFirebase().build();
|
getFirebase().build();
|
||||||
@@ -380,8 +352,6 @@ public class MxisdConfig {
|
|||||||
getThreepid().build();
|
getThreepid().build();
|
||||||
getView().build();
|
getView().build();
|
||||||
getWordpress().build();
|
getWordpress().build();
|
||||||
getPolicy().build();
|
|
||||||
getHashing().build();
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
package io.kamax.mxisd.config;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class PolicyConfig {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(PolicyConfig.class);
|
|
||||||
|
|
||||||
private Map<String, PolicyObject> policies = new HashMap<>();
|
|
||||||
|
|
||||||
public static class TermObject {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PolicyObject {
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
private Map<String, TermObject> terms;
|
|
||||||
|
|
||||||
private List<String> regexp = new ArrayList<>();
|
|
||||||
|
|
||||||
private transient List<Pattern> patterns = new ArrayList<>();
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, TermObject> getTerms() {
|
|
||||||
return terms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTerms(Map<String, TermObject> terms) {
|
|
||||||
this.terms = terms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getRegexp() {
|
|
||||||
return regexp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRegexp(List<String> regexp) {
|
|
||||||
this.regexp = regexp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pattern> getPatterns() {
|
|
||||||
return patterns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, PolicyObject> getPolicies() {
|
|
||||||
return policies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPolicies(Map<String, PolicyObject> policies) {
|
|
||||||
this.policies = policies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void build() {
|
|
||||||
LOGGER.info("--- Policy Config ---");
|
|
||||||
if (getPolicies().isEmpty()) {
|
|
||||||
LOGGER.info("Empty");
|
|
||||||
} else {
|
|
||||||
for (Map.Entry<String, PolicyObject> policyObjectItem : getPolicies().entrySet()) {
|
|
||||||
PolicyObject policyObject = policyObjectItem.getValue();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Policy \"").append(policyObjectItem.getKey()).append("\"\n");
|
|
||||||
sb.append(" version: ").append(policyObject.getVersion()).append("\n");
|
|
||||||
for (String regexp : policyObjectItem.getValue().getRegexp()) {
|
|
||||||
sb.append(" - ").append(regexp).append("\n");
|
|
||||||
policyObjectItem.getValue().getPatterns().add(Pattern.compile(regexp));
|
|
||||||
}
|
|
||||||
sb.append(" terms:\n");
|
|
||||||
for (Map.Entry<String, TermObject> termItem : policyObject.getTerms().entrySet()) {
|
|
||||||
sb.append(" - lang: ").append(termItem.getKey()).append("\n");
|
|
||||||
sb.append(" name: ").append(termItem.getValue().getName()).append("\n");
|
|
||||||
sb.append(" url: ").append(termItem.getValue().getUrl()).append("\n");
|
|
||||||
}
|
|
||||||
LOGGER.info(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -79,4 +79,5 @@ public class ServerConfig {
|
|||||||
log.info("Port: {}", getPort());
|
log.info("Port: {}", getPort());
|
||||||
log.info("Public URL: {}", getPublicUrl());
|
log.info("Public URL: {}", getPublicUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ public class SessionConfig {
|
|||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
private boolean notifications = true;
|
||||||
|
|
||||||
public boolean getEnabled() {
|
public boolean getEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
@@ -55,11 +57,20 @@ public class SessionConfig {
|
|||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldNotify() {
|
||||||
|
return notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotifications(boolean notifications) {
|
||||||
|
this.notifications = notifications;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Policy() {
|
public Policy() {
|
||||||
validation.enabled = true;
|
validation.enabled = true;
|
||||||
unbind.enabled = true;
|
unbind.enabled = true;
|
||||||
|
unbind.notifications = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PolicyTemplate validation = new PolicyTemplate();
|
private PolicyTemplate validation = new PolicyTemplate();
|
||||||
|
|||||||
@@ -124,18 +124,6 @@ public abstract class SqlConfig {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Lookup {
|
|
||||||
private String query;
|
|
||||||
|
|
||||||
public String getQuery() {
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuery(String query) {
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Identity {
|
public static class Identity {
|
||||||
|
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
@@ -276,7 +264,6 @@ public abstract class SqlConfig {
|
|||||||
private Directory directory = new Directory();
|
private Directory directory = new Directory();
|
||||||
private Identity identity = new Identity();
|
private Identity identity = new Identity();
|
||||||
private Profile profile = new Profile();
|
private Profile profile = new Profile();
|
||||||
private Lookup lookup = new Lookup();
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
@@ -334,14 +321,6 @@ public abstract class SqlConfig {
|
|||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lookup getLookup() {
|
|
||||||
return lookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLookup(Lookup lookup) {
|
|
||||||
this.lookup = lookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract String getProviderName();
|
protected abstract String getProviderName();
|
||||||
|
|
||||||
public void build() {
|
public void build() {
|
||||||
@@ -375,7 +354,6 @@ public abstract class SqlConfig {
|
|||||||
log.info("Identity type: {}", getIdentity().getType());
|
log.info("Identity type: {}", getIdentity().getType());
|
||||||
log.info("3PID mapping query: {}", getIdentity().getQuery());
|
log.info("3PID mapping query: {}", getIdentity().getQuery());
|
||||||
log.info("Identity medium queries: {}", GsonUtil.build().toJson(getIdentity().getMedium()));
|
log.info("Identity medium queries: {}", GsonUtil.build().toJson(getIdentity().getMedium()));
|
||||||
log.info("Lookup query: {}", getLookup().getQuery());
|
|
||||||
log.info("Profile:");
|
log.info("Profile:");
|
||||||
log.info(" Enabled: {}", getProfile().isEnabled());
|
log.info(" Enabled: {}", getProfile().isEnabled());
|
||||||
if (getProfile().isEnabled()) {
|
if (getProfile().isEnabled()) {
|
||||||
|
|||||||
@@ -1,27 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.exception;
|
|
||||||
|
|
||||||
public class InvalidParamException extends RuntimeException {
|
|
||||||
|
|
||||||
public InvalidParamException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.exception;
|
|
||||||
|
|
||||||
public class InvalidPepperException extends RuntimeException {
|
|
||||||
|
|
||||||
public InvalidPepperException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash;
|
|
||||||
|
|
||||||
import io.kamax.matrix.codec.MxSha256;
|
|
||||||
import io.kamax.mxisd.config.HashingConfig;
|
|
||||||
import io.kamax.mxisd.hash.storage.HashStorage;
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HashEngine {
|
|
||||||
|
|
||||||
private final List<? extends IThreePidProvider> providers;
|
|
||||||
private final HashStorage hashStorage;
|
|
||||||
private final MxSha256 sha256 = new MxSha256();
|
|
||||||
private final HashingConfig config;
|
|
||||||
private String pepper;
|
|
||||||
|
|
||||||
public HashEngine(List<? extends IThreePidProvider> providers, HashStorage hashStorage, HashingConfig config) {
|
|
||||||
this.providers = providers;
|
|
||||||
this.hashStorage = hashStorage;
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateHashes() {
|
|
||||||
synchronized (hashStorage) {
|
|
||||||
this.pepper = newPepper();
|
|
||||||
hashStorage.clear();
|
|
||||||
for (IThreePidProvider provider : providers) {
|
|
||||||
for (ThreePidMapping pidMapping : provider.populateHashes()) {
|
|
||||||
hashStorage.add(pidMapping, hash(pidMapping));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPepper() {
|
|
||||||
synchronized (hashStorage) {
|
|
||||||
return pepper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String hash(ThreePidMapping pidMapping) {
|
|
||||||
return sha256.hash(pidMapping.getMedium() + " " + pidMapping.getValue() + " " + getPepper());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String newPepper() {
|
|
||||||
return RandomStringUtils.random(config.getPepperLength());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.config.HashingConfig;
|
|
||||||
import io.kamax.mxisd.hash.rotation.HashRotationStrategy;
|
|
||||||
import io.kamax.mxisd.hash.rotation.NoOpRotationStrategy;
|
|
||||||
import io.kamax.mxisd.hash.rotation.RotationPerRequests;
|
|
||||||
import io.kamax.mxisd.hash.rotation.TimeBasedRotation;
|
|
||||||
import io.kamax.mxisd.hash.storage.EmptyStorage;
|
|
||||||
import io.kamax.mxisd.hash.storage.HashStorage;
|
|
||||||
import io.kamax.mxisd.hash.storage.InMemoryHashStorage;
|
|
||||||
import io.kamax.mxisd.hash.storage.SqlHashStorage;
|
|
||||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
|
||||||
import io.kamax.mxisd.storage.IStorage;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
public class HashManager {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HashManager.class);
|
|
||||||
|
|
||||||
private HashEngine hashEngine;
|
|
||||||
private HashRotationStrategy rotationStrategy;
|
|
||||||
private HashStorage hashStorage;
|
|
||||||
private HashingConfig config;
|
|
||||||
private IStorage storage;
|
|
||||||
private AtomicBoolean configured = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
public void init(HashingConfig config, List<? extends IThreePidProvider> providers, IStorage storage) {
|
|
||||||
this.config = config;
|
|
||||||
this.storage = storage;
|
|
||||||
initStorage();
|
|
||||||
hashEngine = new HashEngine(providers, getHashStorage(), config);
|
|
||||||
initRotationStrategy();
|
|
||||||
configured.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initStorage() {
|
|
||||||
if (config.isEnabled()) {
|
|
||||||
switch (config.getHashStorageType()) {
|
|
||||||
case IN_MEMORY:
|
|
||||||
this.hashStorage = new InMemoryHashStorage();
|
|
||||||
break;
|
|
||||||
case SQL:
|
|
||||||
this.hashStorage = new SqlHashStorage(storage);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown storage type: " + config.getHashStorageType());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.hashStorage = new EmptyStorage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initRotationStrategy() {
|
|
||||||
if (config.isEnabled()) {
|
|
||||||
switch (config.getRotationPolicy()) {
|
|
||||||
case PER_REQUESTS:
|
|
||||||
this.rotationStrategy = new RotationPerRequests();
|
|
||||||
break;
|
|
||||||
case PER_SECONDS:
|
|
||||||
this.rotationStrategy = new TimeBasedRotation(config.getDelay());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown rotation type: " + config.getHashStorageType());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.rotationStrategy = new NoOpRotationStrategy();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.rotationStrategy.register(getHashEngine());
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashEngine getHashEngine() {
|
|
||||||
return hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashRotationStrategy getRotationStrategy() {
|
|
||||||
return rotationStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashStorage getHashStorage() {
|
|
||||||
return hashStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashingConfig getConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.rotation;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.hash.HashEngine;
|
|
||||||
|
|
||||||
public interface HashRotationStrategy {
|
|
||||||
|
|
||||||
void register(HashEngine hashEngine);
|
|
||||||
|
|
||||||
HashEngine getHashEngine();
|
|
||||||
|
|
||||||
void newRequest();
|
|
||||||
|
|
||||||
default void trigger() {
|
|
||||||
getHashEngine().updateHashes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.rotation;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.hash.HashEngine;
|
|
||||||
|
|
||||||
public class NoOpRotationStrategy implements HashRotationStrategy {
|
|
||||||
|
|
||||||
private HashEngine hashEngine;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(HashEngine hashEngine) {
|
|
||||||
this.hashEngine = hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HashEngine getHashEngine() {
|
|
||||||
return hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void newRequest() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.rotation;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.hash.HashEngine;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class RotationPerRequests implements HashRotationStrategy {
|
|
||||||
|
|
||||||
private HashEngine hashEngine;
|
|
||||||
private final AtomicInteger counter = new AtomicInteger(0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(HashEngine hashEngine) {
|
|
||||||
this.hashEngine = hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HashEngine getHashEngine() {
|
|
||||||
return hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void newRequest() {
|
|
||||||
int newValue = counter.incrementAndGet();
|
|
||||||
if (newValue >= 10) {
|
|
||||||
counter.set(0);
|
|
||||||
trigger();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.rotation;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.hash.HashEngine;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class TimeBasedRotation implements HashRotationStrategy {
|
|
||||||
|
|
||||||
private final long delay;
|
|
||||||
private HashEngine hashEngine;
|
|
||||||
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
|
|
||||||
public TimeBasedRotation(long delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(HashEngine hashEngine) {
|
|
||||||
this.hashEngine = hashEngine;
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(executorService::shutdown));
|
|
||||||
executorService.scheduleWithFixedDelay(this::trigger, 0, delay, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HashEngine getHashEngine() {
|
|
||||||
return hashEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void newRequest() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.storage;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class EmptyStorage implements HashStorage {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Pair<String, ThreePidMapping>> find(Iterable<String> hashes) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(ThreePidMapping pidMapping, String hash) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.storage;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface HashStorage {
|
|
||||||
|
|
||||||
Collection<Pair<String, ThreePidMapping>> find(Iterable<String> hashes);
|
|
||||||
|
|
||||||
void add(ThreePidMapping pidMapping, String hash);
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.storage;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class InMemoryHashStorage implements HashStorage {
|
|
||||||
|
|
||||||
private final Map<String, ThreePidMapping> mapping = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Pair<String, ThreePidMapping>> find(Iterable<String> hashes) {
|
|
||||||
List<Pair<String, ThreePidMapping>> result = new ArrayList<>();
|
|
||||||
for (String hash : hashes) {
|
|
||||||
ThreePidMapping pidMapping = mapping.get(hash);
|
|
||||||
if (pidMapping != null) {
|
|
||||||
result.add(Pair.of(hash, pidMapping));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(ThreePidMapping pidMapping, String hash) {
|
|
||||||
mapping.put(hash, pidMapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
mapping.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package io.kamax.mxisd.hash.storage;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import io.kamax.mxisd.storage.IStorage;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class SqlHashStorage implements HashStorage {
|
|
||||||
|
|
||||||
private final IStorage storage;
|
|
||||||
|
|
||||||
public SqlHashStorage(IStorage storage) {
|
|
||||||
this.storage = storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Pair<String, ThreePidMapping>> find(Iterable<String> hashes) {
|
|
||||||
return storage.findHashes(hashes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(ThreePidMapping pidMapping, String hash) {
|
|
||||||
storage.addHash(pidMapping.getMxid(), pidMapping.getMedium(), pidMapping.getValue(), hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
storage.clearHashes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,6 +25,8 @@ 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) {
|
public static String getValidate(String medium, String sid, String secret, String token) {
|
||||||
return String.format("%s/validate/%s/submitToken?sid=%s&client_secret=%s&token=%s", Base, medium, sid, secret, token);
|
// FIXME use some kind of URLBuilder
|
||||||
|
return Base + "/validate/" + medium + "/submitToken?sid=" + sid + "&client_secret=" + secret + "&token=" + token;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http;
|
|
||||||
|
|
||||||
public class IsAPIv2 {
|
|
||||||
|
|
||||||
public static final String Base = "/_matrix/identity/v2";
|
|
||||||
|
|
||||||
public static String getValidate(String medium, String sid, String secret, String token) {
|
|
||||||
return String.format("%s/validate/%s/submitToken?sid=%s&client_secret=%s&token=%s", Base, medium, sid, secret, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.io.identity;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ClientHashLookupAnswer {
|
|
||||||
|
|
||||||
private Map<String, String> mappings = new HashMap<>();
|
|
||||||
|
|
||||||
public Map<String, String> getMappings() {
|
|
||||||
return mappings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.io.identity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ClientHashLookupRequest {
|
|
||||||
|
|
||||||
private String algorithm;
|
|
||||||
private String pepper;
|
|
||||||
private List<String> addresses = new ArrayList<>();
|
|
||||||
|
|
||||||
public String getAlgorithm() {
|
|
||||||
return algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlgorithm(String algorithm) {
|
|
||||||
this.algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPepper() {
|
|
||||||
return pepper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPepper(String pepper) {
|
|
||||||
this.pepper = pepper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getAddresses() {
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddresses(List<String> addresses) {
|
|
||||||
this.addresses = addresses;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package io.kamax.mxisd.http.undertow.handler;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.http.IsAPIv1;
|
|
||||||
import io.kamax.mxisd.http.IsAPIv2;
|
|
||||||
import io.kamax.mxisd.matrix.IdentityServiceAPI;
|
|
||||||
import io.undertow.server.HttpHandler;
|
|
||||||
|
|
||||||
public interface ApiHandler extends HttpHandler {
|
|
||||||
|
|
||||||
default String getPath(IdentityServiceAPI api) {
|
|
||||||
switch (api) {
|
|
||||||
case V2:
|
|
||||||
return IsAPIv2.Base + getHandlerPath();
|
|
||||||
case V1:
|
|
||||||
return IsAPIv1.Base + getHandlerPath();
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown api version: " + api);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String getHandlerPath();
|
|
||||||
}
|
|
||||||
@@ -1,69 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import io.undertow.server.HttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class AuthorizationHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AuthorizationHandler.class);
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
private final HttpHandler child;
|
|
||||||
|
|
||||||
public static AuthorizationHandler around(AccountManager accountManager, HttpHandler child) {
|
|
||||||
return new AuthorizationHandler(accountManager, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthorizationHandler(AccountManager accountManager, HttpHandler child) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
this.child = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
String token = findAccessToken(exchange).orElse(null);
|
|
||||||
if (token == null) {
|
|
||||||
log.error("Unauthorized request from: {}", exchange.getHostAndPort());
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountDao account = accountManager.findAccount(token);
|
|
||||||
if (account == null) {
|
|
||||||
log.error("Account not found from request from: {}", exchange.getHostAndPort());
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
if (account.getExpiresIn() < System.currentTimeMillis()) {
|
|
||||||
log.error("Account for '{}' from: {}", account.getUserId(), exchange.getHostAndPort());
|
|
||||||
accountManager.deleteAccount(token);
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
log.trace("Access for '{}' allowed", account.getUserId());
|
|
||||||
child.handleRequest(exchange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,6 @@ import io.kamax.mxisd.exception.AccessTokenNotFoundException;
|
|||||||
import io.kamax.mxisd.exception.HttpMatrixException;
|
import io.kamax.mxisd.exception.HttpMatrixException;
|
||||||
import io.kamax.mxisd.exception.InternalServerError;
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
import io.kamax.mxisd.proxy.Response;
|
import io.kamax.mxisd.proxy.Response;
|
||||||
import io.kamax.mxisd.util.OptionalUtil;
|
|
||||||
import io.kamax.mxisd.util.RestClientUtils;
|
import io.kamax.mxisd.util.RestClientUtils;
|
||||||
import io.undertow.server.HttpHandler;
|
import io.undertow.server.HttpHandler;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
@@ -56,24 +55,6 @@ public abstract class BasicHttpHandler implements HttpHandler {
|
|||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BasicHttpHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(BasicHttpHandler.class);
|
||||||
|
|
||||||
protected final static String headerName = "Authorization";
|
|
||||||
protected final static String headerValuePrefix = "Bearer ";
|
|
||||||
private final static String parameterName = "access_token";
|
|
||||||
|
|
||||||
Optional<String> findAccessTokenInHeaders(HttpServerExchange exchange) {
|
|
||||||
return Optional.ofNullable(exchange.getRequestHeaders().getFirst(headerName))
|
|
||||||
.filter(header -> StringUtils.startsWith(header, headerValuePrefix))
|
|
||||||
.map(header -> header.substring(headerValuePrefix.length()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<String> findAccessTokenInQuery(HttpServerExchange exchange) {
|
|
||||||
return Optional.ofNullable(exchange.getQueryParameters().getOrDefault(parameterName, new LinkedList<>()).peekFirst());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<String> findAccessToken(HttpServerExchange exchange) {
|
|
||||||
return OptionalUtil.findFirst(() -> findAccessTokenInHeaders(exchange), () -> findAccessTokenInQuery(exchange));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getAccessToken(HttpServerExchange exchange) {
|
protected String getAccessToken(HttpServerExchange exchange) {
|
||||||
return Optional.ofNullable(exchange.getRequestHeaders().getFirst("Authorization"))
|
return Optional.ofNullable(exchange.getRequestHeaders().getFirst("Authorization"))
|
||||||
.flatMap(v -> {
|
.flatMap(v -> {
|
||||||
|
|||||||
@@ -1,70 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import io.undertow.server.HttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CheckTermsHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(CheckTermsHandler.class);
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
private final HttpHandler child;
|
|
||||||
|
|
||||||
private final List<PolicyConfig.PolicyObject> policies;
|
|
||||||
|
|
||||||
public static CheckTermsHandler around(AccountManager accountManager, HttpHandler child, List<PolicyConfig.PolicyObject> policies) {
|
|
||||||
return new CheckTermsHandler(accountManager, child, policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CheckTermsHandler(AccountManager accountManager, HttpHandler child,
|
|
||||||
List<PolicyConfig.PolicyObject> policies) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
this.child = child;
|
|
||||||
this.policies = policies;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
String token = findAccessToken(exchange).orElse(null);
|
|
||||||
if (token == null) {
|
|
||||||
log.error("Unauthorized request from: {}", exchange.getHostAndPort());
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!accountManager.isTermAccepted(token, policies)) {
|
|
||||||
log.error("Non accepting request from: {}", exchange.getHostAndPort());
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
log.trace("Access granted");
|
|
||||||
child.handleRequest(exchange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,11 +21,35 @@
|
|||||||
package io.kamax.mxisd.http.undertow.handler;
|
package io.kamax.mxisd.http.undertow.handler;
|
||||||
|
|
||||||
import io.kamax.mxisd.exception.AccessTokenNotFoundException;
|
import io.kamax.mxisd.exception.AccessTokenNotFoundException;
|
||||||
|
import io.kamax.mxisd.util.OptionalUtil;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class HomeserverProxyHandler extends BasicHttpHandler {
|
public abstract class HomeserverProxyHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
protected final static String headerName = "Authorization";
|
||||||
|
protected final static String headerValuePrefix = "Bearer ";
|
||||||
|
private final static String parameterName = "access_token";
|
||||||
|
|
||||||
|
Optional<String> findAccessTokenInHeaders(HttpServerExchange exchange) {
|
||||||
|
return Optional.ofNullable(exchange.getRequestHeaders().getFirst(headerName))
|
||||||
|
.filter(header -> StringUtils.startsWith(header, headerValuePrefix))
|
||||||
|
.map(header -> header.substring(headerValuePrefix.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<String> findAccessTokenInQuery(HttpServerExchange exchange) {
|
||||||
|
return Optional.ofNullable(exchange.getQueryParameters().getOrDefault(parameterName, new LinkedList<>()).peekFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> findAccessToken(HttpServerExchange exchange) {
|
||||||
|
return OptionalUtil.findFirst(() -> findAccessTokenInHeaders(exchange), () -> findAccessTokenInQuery(exchange));
|
||||||
|
}
|
||||||
|
|
||||||
public String getAccessToken(HttpServerExchange exchange) {
|
public String getAccessToken(HttpServerExchange exchange) {
|
||||||
return findAccessToken(exchange).orElseThrow(AccessTokenNotFoundException::new);
|
return findAccessToken(exchange).orElseThrow(AccessTokenNotFoundException::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ public class SaneHandler extends BasicHttpHandler {
|
|||||||
respond(exchange, HttpStatus.SC_NOT_FOUND, "M_NOT_FOUND", e.getMessage());
|
respond(exchange, HttpStatus.SC_NOT_FOUND, "M_NOT_FOUND", e.getMessage());
|
||||||
} catch (NotImplementedException e) {
|
} catch (NotImplementedException e) {
|
||||||
respond(exchange, HttpStatus.SC_NOT_IMPLEMENTED, "M_NOT_IMPLEMENTED", e.getMessage());
|
respond(exchange, HttpStatus.SC_NOT_IMPLEMENTED, "M_NOT_IMPLEMENTED", e.getMessage());
|
||||||
} catch (InvalidPepperException e) {
|
|
||||||
respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_INVALID_PEPPER", e.getMessage());
|
|
||||||
} catch (InvalidParamException e) {
|
|
||||||
respond(exchange, HttpStatus.SC_BAD_REQUEST, "M_INVALID_PARAM", e.getMessage());
|
|
||||||
} catch (FeatureNotAvailable e) {
|
} catch (FeatureNotAvailable e) {
|
||||||
if (StringUtils.isNotBlank(e.getInternalReason())) {
|
if (StringUtils.isNotBlank(e.getInternalReason())) {
|
||||||
log.error("Feature not available: {}", e.getInternalReason());
|
log.error("Feature not available: {}", e.getInternalReason());
|
||||||
|
|||||||
@@ -1,52 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.auth.v2;
|
|
||||||
|
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class AccountGetUserInfoHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
public static final String Path = "/_matrix/identity/v2/account";
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AccountGetUserInfoHandler.class);
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
public AccountGetUserInfoHandler(AccountManager accountManager) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) {
|
|
||||||
LOGGER.info("Get User Info.");
|
|
||||||
String token = findAccessToken(exchange).orElseThrow(InvalidCredentialsException::new);
|
|
||||||
|
|
||||||
String userId = accountManager.getUserId(token);
|
|
||||||
LOGGER.info("Account found: {}", userId);
|
|
||||||
respond(exchange, GsonUtil.makeObj("user_id", userId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* mxisd - Matrix Identity Server Daemon
|
|
||||||
* Copyright (C) 2018 Kamax Sarl
|
|
||||||
*
|
|
||||||
* https://www.kamax.io/
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.auth.v2;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class AccountLogoutHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
public static final String Path = "/_matrix/identity/v2/account/logout";
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AccountLogoutHandler.class);
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
public AccountLogoutHandler(AccountManager accountManager) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) {
|
|
||||||
LOGGER.info("Logout.");
|
|
||||||
String token = findAccessToken(exchange).orElseThrow(InvalidCredentialsException::new);
|
|
||||||
|
|
||||||
accountManager.logout(token);
|
|
||||||
|
|
||||||
respondJson(exchange, "{}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.auth.v2;
|
|
||||||
|
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.auth.OpenIdToken;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class AccountRegisterHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
public static final String Path = "/_matrix/identity/v2/account/register";
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AccountRegisterHandler.class);
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
public AccountRegisterHandler(AccountManager accountManager) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) {
|
|
||||||
OpenIdToken openIdToken = parseJsonTo(exchange, OpenIdToken.class);
|
|
||||||
|
|
||||||
if (LOGGER.isInfoEnabled()) {
|
|
||||||
LOGGER.info("Registration from domain: {}, expired at {}", openIdToken.getMatrixServerName(),
|
|
||||||
new Date(openIdToken.getExpiredIn()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String token = accountManager.register(openIdToken);
|
|
||||||
respond(exchange, GsonUtil.makeObj("token", token));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,8 +23,6 @@ package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
|||||||
import io.kamax.mxisd.http.IsAPIv1;
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.io.identity.ClientBulkLookupAnswer;
|
import io.kamax.mxisd.http.io.identity.ClientBulkLookupAnswer;
|
||||||
import io.kamax.mxisd.http.io.identity.ClientBulkLookupRequest;
|
import io.kamax.mxisd.http.io.identity.ClientBulkLookupRequest;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.LookupHandler;
|
|
||||||
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||||
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
||||||
@@ -35,7 +33,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BulkLookupHandler extends LookupHandler implements ApiHandler {
|
public class BulkLookupHandler extends LookupHandler {
|
||||||
|
|
||||||
public static final String Path = IsAPIv1.Base + "/bulk_lookup";
|
public static final String Path = IsAPIv1.Base + "/bulk_lookup";
|
||||||
|
|
||||||
@@ -71,8 +69,4 @@ public class BulkLookupHandler extends LookupHandler implements ApiHandler {
|
|||||||
respondJson(exchange, answer);
|
respondJson(exchange, answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/bulk_lookup";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,16 +18,18 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import io.kamax.mxisd.crypto.KeyManager;
|
import io.kamax.mxisd.crypto.KeyManager;
|
||||||
import io.kamax.mxisd.crypto.KeyType;
|
import io.kamax.mxisd.crypto.KeyType;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class EphemeralKeyIsValidHandler extends KeyIsValidHandler implements ApiHandler {
|
public class EphemeralKeyIsValidHandler extends KeyIsValidHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/pubkey/ephemeral/isvalid";
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(EphemeralKeyIsValidHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(EphemeralKeyIsValidHandler.class);
|
||||||
|
|
||||||
@@ -46,8 +48,4 @@ public class EphemeralKeyIsValidHandler extends KeyIsValidHandler implements Api
|
|||||||
respondJson(exchange, mgr.isValid(KeyType.Ephemeral, pubKey) ? validKey : invalidKey);
|
respondJson(exchange, mgr.isValid(KeyType.Ephemeral, pubKey) ? validKey : invalidKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/pubkey/ephemeral/isvalid";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,21 +18,19 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
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.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
|
|
||||||
public class HelloHandler extends BasicHttpHandler implements ApiHandler {
|
public class HelloHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(HttpServerExchange exchange) {
|
public void handleRequest(HttpServerExchange exchange) {
|
||||||
respondJson(exchange, "{}");
|
respondJson(exchange, "{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,22 +18,23 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.mxisd.crypto.GenericKeyIdentifier;
|
import io.kamax.mxisd.crypto.GenericKeyIdentifier;
|
||||||
import io.kamax.mxisd.crypto.KeyManager;
|
import io.kamax.mxisd.crypto.KeyManager;
|
||||||
import io.kamax.mxisd.crypto.KeyType;
|
import io.kamax.mxisd.crypto.KeyType;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class KeyGetHandler extends BasicHttpHandler implements ApiHandler {
|
public class KeyGetHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
public static final String Key = "key";
|
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 transient final Logger log = LoggerFactory.getLogger(KeyGetHandler.class);
|
||||||
|
|
||||||
@@ -60,8 +61,4 @@ public class KeyGetHandler extends BasicHttpHandler implements ApiHandler {
|
|||||||
respond(exchange, obj);
|
respond(exchange, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/pubkey/{" + Key + "}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
import io.kamax.mxisd.http.io.identity.KeyValidityJson;
|
import io.kamax.mxisd.http.io.identity.KeyValidityJson;
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.lookup.ALookupRequest;
|
import io.kamax.mxisd.lookup.ALookupRequest;
|
||||||
@@ -18,16 +18,18 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import io.kamax.mxisd.crypto.KeyManager;
|
import io.kamax.mxisd.crypto.KeyManager;
|
||||||
import io.kamax.mxisd.crypto.KeyType;
|
import io.kamax.mxisd.crypto.KeyType;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class RegularKeyIsValidHandler extends KeyIsValidHandler implements ApiHandler {
|
public class RegularKeyIsValidHandler extends KeyIsValidHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/pubkey/isvalid";
|
||||||
|
|
||||||
private transient final Logger log = LoggerFactory.getLogger(RegularKeyIsValidHandler.class);
|
private transient final Logger log = LoggerFactory.getLogger(RegularKeyIsValidHandler.class);
|
||||||
|
|
||||||
@@ -46,8 +48,4 @@ public class RegularKeyIsValidHandler extends KeyIsValidHandler implements ApiHa
|
|||||||
respondJson(exchange, mgr.isValid(KeyType.Regular, pubKey) ? validKey : invalidKey);
|
respondJson(exchange, mgr.isValid(KeyType.Regular, pubKey) ? validKey : invalidKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/pubkey/isvalid";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,25 +18,26 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.matrix.ThreePid;
|
import io.kamax.matrix.ThreePid;
|
||||||
import io.kamax.matrix.ThreePidMedium;
|
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.RequestTokenResponse;
|
||||||
import io.kamax.mxisd.http.io.identity.SessionEmailTokenRequestJson;
|
import io.kamax.mxisd.http.io.identity.SessionEmailTokenRequestJson;
|
||||||
import io.kamax.mxisd.http.io.identity.SessionPhoneTokenRequestJson;
|
import io.kamax.mxisd.http.io.identity.SessionPhoneTokenRequestJson;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.session.SessionManager;
|
import io.kamax.mxisd.session.SessionManager;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SessionStartHandler extends BasicHttpHandler implements ApiHandler {
|
public class SessionStartHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
public static final String Medium = "medium";
|
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 transient final Logger log = LoggerFactory.getLogger(SessionStartHandler.class);
|
||||||
|
|
||||||
@@ -83,8 +84,4 @@ public class SessionStartHandler extends BasicHttpHandler implements ApiHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/validate/{" + Medium + "}/requestToken";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,16 +18,16 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
import io.kamax.mxisd.crypto.SignatureManager;
|
import io.kamax.mxisd.crypto.SignatureManager;
|
||||||
import io.kamax.mxisd.exception.BadRequestException;
|
import io.kamax.mxisd.exception.BadRequestException;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.io.identity.BindRequest;
|
import io.kamax.mxisd.http.io.identity.BindRequest;
|
||||||
import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson;
|
import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.invitation.InvitationManager;
|
import io.kamax.mxisd.invitation.InvitationManager;
|
||||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||||
import io.kamax.mxisd.session.SessionManager;
|
import io.kamax.mxisd.session.SessionManager;
|
||||||
@@ -42,7 +42,9 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class SessionTpidBindHandler extends BasicHttpHandler implements ApiHandler {
|
public class SessionTpidBindHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/3pid/bind";
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SessionTpidBindHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(SessionTpidBindHandler.class);
|
||||||
|
|
||||||
@@ -95,8 +97,4 @@ public class SessionTpidBindHandler extends BasicHttpHandler implements ApiHandl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/3pid/bind";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,19 +18,21 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.mxisd.exception.SessionNotValidatedException;
|
import io.kamax.mxisd.exception.SessionNotValidatedException;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidValidation;
|
import io.kamax.mxisd.lookup.ThreePidValidation;
|
||||||
import io.kamax.mxisd.session.SessionManager;
|
import io.kamax.mxisd.session.SessionManager;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SessionTpidGetValidatedHandler extends BasicHttpHandler implements ApiHandler {
|
public class SessionTpidGetValidatedHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/3pid/getValidated3pid";
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SessionTpidGetValidatedHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(SessionTpidGetValidatedHandler.class);
|
||||||
|
|
||||||
@@ -60,8 +62,4 @@ public class SessionTpidGetValidatedHandler extends BasicHttpHandler implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/3pid/getValidated3pid";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,17 +18,19 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.session.SessionManager;
|
import io.kamax.mxisd.session.SessionManager;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SessionTpidUnbindHandler extends BasicHttpHandler implements ApiHandler {
|
public class SessionTpidUnbindHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/3pid/unbind";
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SessionTpidUnbindHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(SessionTpidUnbindHandler.class);
|
||||||
|
|
||||||
@@ -46,9 +48,4 @@ public class SessionTpidUnbindHandler extends BasicHttpHandler implements ApiHan
|
|||||||
sessionMgr.unbind(auth, body);
|
sessionMgr.unbind(auth, body);
|
||||||
writeBodyAsUtf8(exchange, "{}");
|
writeBodyAsUtf8(exchange, "{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/3pid/unbind";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,17 +18,19 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
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.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.session.SessionManager;
|
import io.kamax.mxisd.session.SessionManager;
|
||||||
import io.kamax.mxisd.session.ValidationResult;
|
import io.kamax.mxisd.session.ValidationResult;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public abstract class SessionValidateHandler extends BasicHttpHandler implements ApiHandler {
|
public abstract class SessionValidateHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/validate/{medium}/submitToken";
|
||||||
|
|
||||||
private transient final Logger log = LoggerFactory.getLogger(SessionValidateHandler.class);
|
private transient final Logger log = LoggerFactory.getLogger(SessionValidateHandler.class);
|
||||||
|
|
||||||
@@ -50,8 +52,4 @@ public abstract class SessionValidateHandler extends BasicHttpHandler implements
|
|||||||
return mgr.validate(sid, secret, token);
|
return mgr.validate(sid, secret, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/validate/{medium}/submitToken";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import io.kamax.mxisd.config.MxisdConfig;
|
import io.kamax.mxisd.config.MxisdConfig;
|
||||||
import io.kamax.mxisd.config.ServerConfig;
|
import io.kamax.mxisd.config.ServerConfig;
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.kamax.matrix.MatrixID;
|
import io.kamax.matrix.MatrixID;
|
||||||
@@ -27,15 +27,17 @@ import io.kamax.matrix.json.GsonUtil;
|
|||||||
import io.kamax.matrix.json.MatrixJson;
|
import io.kamax.matrix.json.MatrixJson;
|
||||||
import io.kamax.mxisd.config.MxisdConfig;
|
import io.kamax.mxisd.config.MxisdConfig;
|
||||||
import io.kamax.mxisd.crypto.SignatureManager;
|
import io.kamax.mxisd.crypto.SignatureManager;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||||
import io.kamax.mxisd.invitation.InvitationManager;
|
import io.kamax.mxisd.invitation.InvitationManager;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SignEd25519Handler extends BasicHttpHandler implements ApiHandler {
|
public class SignEd25519Handler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/sign-ed25519";
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SignEd25519Handler.class);
|
private static final Logger log = LoggerFactory.getLogger(SignEd25519Handler.class);
|
||||||
|
|
||||||
@@ -70,8 +72,4 @@ public class SignEd25519Handler extends BasicHttpHandler implements ApiHandler {
|
|||||||
respondJson(exchange, res);
|
respondJson(exchange, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/sign-ed25519";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,6 @@ import io.kamax.mxisd.config.ServerConfig;
|
|||||||
import io.kamax.mxisd.crypto.SignatureManager;
|
import io.kamax.mxisd.crypto.SignatureManager;
|
||||||
import io.kamax.mxisd.http.IsAPIv1;
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson;
|
import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.LookupHandler;
|
|
||||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||||
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
||||||
@@ -38,7 +36,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class SingleLookupHandler extends LookupHandler implements ApiHandler {
|
public class SingleLookupHandler extends LookupHandler {
|
||||||
|
|
||||||
public static final String Path = IsAPIv1.Base + "/lookup";
|
public static final String Path = IsAPIv1.Base + "/lookup";
|
||||||
|
|
||||||
@@ -79,8 +77,4 @@ public class SingleLookupHandler extends LookupHandler implements ApiHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/lookup";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.share;
|
package io.kamax.mxisd.http.undertow.handler.identity.v1;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
@@ -28,10 +28,10 @@ import io.kamax.matrix.json.GsonUtil;
|
|||||||
import io.kamax.mxisd.config.ServerConfig;
|
import io.kamax.mxisd.config.ServerConfig;
|
||||||
import io.kamax.mxisd.crypto.KeyManager;
|
import io.kamax.mxisd.crypto.KeyManager;
|
||||||
import io.kamax.mxisd.exception.BadRequestException;
|
import io.kamax.mxisd.exception.BadRequestException;
|
||||||
|
import io.kamax.mxisd.http.IsAPIv1;
|
||||||
import io.kamax.mxisd.http.io.identity.StoreInviteRequest;
|
import io.kamax.mxisd.http.io.identity.StoreInviteRequest;
|
||||||
import io.kamax.mxisd.http.io.identity.ThreePidInviteReplyIO;
|
import io.kamax.mxisd.http.io.identity.ThreePidInviteReplyIO;
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.invitation.IThreePidInvite;
|
import io.kamax.mxisd.invitation.IThreePidInvite;
|
||||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||||
import io.kamax.mxisd.invitation.InvitationManager;
|
import io.kamax.mxisd.invitation.InvitationManager;
|
||||||
@@ -45,7 +45,9 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class StoreInviteHandler extends BasicHttpHandler implements ApiHandler {
|
public class StoreInviteHandler extends BasicHttpHandler {
|
||||||
|
|
||||||
|
public static final String Path = IsAPIv1.Base + "/store-invite";
|
||||||
|
|
||||||
private ServerConfig cfg;
|
private ServerConfig cfg;
|
||||||
private InvitationManager invMgr;
|
private InvitationManager invMgr;
|
||||||
@@ -98,8 +100,4 @@ public class StoreInviteHandler extends BasicHttpHandler implements ApiHandler {
|
|||||||
respondJson(exchange, new ThreePidInviteReplyIO(reply, keyMgr.getPublicKeyBase64(keyMgr.getServerSigningKey().getId()), cfg.getPublicUrl()));
|
respondJson(exchange, new ThreePidInviteReplyIO(reply, keyMgr.getPublicKeyBase64(keyMgr.getServerSigningKey().getId()), cfg.getPublicUrl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/store-invite";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package io.kamax.mxisd.http.undertow.handler.identity.v2;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import io.kamax.mxisd.config.HashingConfig;
|
|
||||||
import io.kamax.mxisd.hash.HashManager;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
|
|
||||||
public class HashDetailsHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
public static final String PATH = "/_matrix/identity/v2/hash_details";
|
|
||||||
|
|
||||||
private final HashManager hashManager;
|
|
||||||
|
|
||||||
public HashDetailsHandler(HashManager hashManager) {
|
|
||||||
this.hashManager = hashManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
respond(exchange, getResponse());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getResponse() {
|
|
||||||
JsonObject response = new JsonObject();
|
|
||||||
response.addProperty("lookup_pepper", hashManager.getHashEngine().getPepper());
|
|
||||||
JsonArray algorithms = new JsonArray();
|
|
||||||
HashingConfig config = hashManager.getConfig();
|
|
||||||
if (config.isEnabled()) {
|
|
||||||
for (HashingConfig.Algorithm algorithm : config.getAlgorithms()) {
|
|
||||||
algorithms.add(algorithm.name().toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response.add("algorithms", algorithms);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,130 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.http.undertow.handler.identity.v2;
|
|
||||||
|
|
||||||
import io.kamax.mxisd.config.HashingConfig;
|
|
||||||
import io.kamax.mxisd.exception.InvalidParamException;
|
|
||||||
import io.kamax.mxisd.exception.InvalidPepperException;
|
|
||||||
import io.kamax.mxisd.hash.HashManager;
|
|
||||||
import io.kamax.mxisd.http.IsAPIv2;
|
|
||||||
import io.kamax.mxisd.http.io.identity.ClientHashLookupAnswer;
|
|
||||||
import io.kamax.mxisd.http.io.identity.ClientHashLookupRequest;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.ApiHandler;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.identity.share.LookupHandler;
|
|
||||||
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
|
||||||
import io.kamax.mxisd.lookup.HashLookupRequest;
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HashLookupHandler extends LookupHandler implements ApiHandler {
|
|
||||||
|
|
||||||
public static final String Path = IsAPIv2.Base + "/lookup";
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(HashLookupHandler.class);
|
|
||||||
|
|
||||||
private LookupStrategy strategy;
|
|
||||||
private HashManager hashManager;
|
|
||||||
|
|
||||||
public HashLookupHandler(LookupStrategy strategy, HashManager hashManager) {
|
|
||||||
this.strategy = strategy;
|
|
||||||
this.hashManager = hashManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
ClientHashLookupRequest input = parseJsonTo(exchange, ClientHashLookupRequest.class);
|
|
||||||
HashLookupRequest lookupRequest = new HashLookupRequest();
|
|
||||||
setRequesterInfo(lookupRequest, exchange);
|
|
||||||
log.info("Got bulk lookup request from {} with client {} - Is recursive? {}",
|
|
||||||
lookupRequest.getRequester(), lookupRequest.getUserAgent(), lookupRequest.isRecursive());
|
|
||||||
|
|
||||||
if (!hashManager.getConfig().isEnabled()) {
|
|
||||||
throw new InvalidParamException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hashManager.getHashEngine().getPepper().equals(input.getPepper())) {
|
|
||||||
throw new InvalidPepperException();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (input.getAlgorithm()) {
|
|
||||||
case "none":
|
|
||||||
noneAlgorithm(exchange, lookupRequest, input);
|
|
||||||
break;
|
|
||||||
case "sha256":
|
|
||||||
sha256Algorithm(exchange, lookupRequest, input);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new InvalidParamException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void noneAlgorithm(HttpServerExchange exchange, HashLookupRequest request, ClientHashLookupRequest input) throws Exception {
|
|
||||||
if (!hashManager.getConfig().getAlgorithms().contains(HashingConfig.Algorithm.NONE)) {
|
|
||||||
throw new InvalidParamException();
|
|
||||||
}
|
|
||||||
|
|
||||||
BulkLookupRequest bulkLookupRequest = new BulkLookupRequest();
|
|
||||||
List<ThreePidMapping> mappings = new ArrayList<>();
|
|
||||||
for (String address : input.getAddresses()) {
|
|
||||||
String[] parts = address.split(" ");
|
|
||||||
ThreePidMapping mapping = new ThreePidMapping();
|
|
||||||
mapping.setMedium(parts[0]);
|
|
||||||
mapping.setValue(parts[1]);
|
|
||||||
mappings.add(mapping);
|
|
||||||
}
|
|
||||||
bulkLookupRequest.setMappings(mappings);
|
|
||||||
|
|
||||||
ClientHashLookupAnswer answer = new ClientHashLookupAnswer();
|
|
||||||
|
|
||||||
for (ThreePidMapping mapping : strategy.find(bulkLookupRequest).get()) {
|
|
||||||
answer.getMappings().put(mapping.getMedium() + " " + mapping.getValue(), mapping.getMxid());
|
|
||||||
}
|
|
||||||
log.info("Finished bulk lookup request from {}", request.getRequester());
|
|
||||||
|
|
||||||
respondJson(exchange, answer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sha256Algorithm(HttpServerExchange exchange, HashLookupRequest request, ClientHashLookupRequest input) {
|
|
||||||
if (!hashManager.getConfig().getAlgorithms().contains(HashingConfig.Algorithm.SHA256)) {
|
|
||||||
throw new InvalidParamException();
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientHashLookupAnswer answer = new ClientHashLookupAnswer();
|
|
||||||
for (Pair<String, ThreePidMapping> pair : hashManager.getHashStorage().find(request.getHashes())) {
|
|
||||||
answer.getMappings().put(pair.getKey(), pair.getValue().getMxid());
|
|
||||||
}
|
|
||||||
log.info("Finished bulk lookup request from {}", request.getRequester());
|
|
||||||
|
|
||||||
respondJson(exchange, answer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHandlerPath() {
|
|
||||||
return "/bulk_lookup";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package io.kamax.mxisd.http.undertow.handler.term.v2;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import io.kamax.matrix.json.GsonUtil;
|
|
||||||
import io.kamax.mxisd.auth.AccountManager;
|
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class AcceptTermsHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AcceptTermsHandler.class);
|
|
||||||
|
|
||||||
public static final String PATH = "/_matrix/identity/v2/terms";
|
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
|
|
||||||
public AcceptTermsHandler(AccountManager accountManager) {
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
String token = getAccessToken(exchange);
|
|
||||||
|
|
||||||
JsonObject request = parseJsonObject(exchange);
|
|
||||||
JsonObject accepts = GsonUtil.getObj(request, "user_accepts");
|
|
||||||
AccountDao account = accountManager.findAccount(token);
|
|
||||||
|
|
||||||
if (account == null) {
|
|
||||||
throw new InvalidCredentialsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accepts == null || accepts.isJsonNull()) {
|
|
||||||
respondJson(exchange, "{}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accepts.isJsonArray()) {
|
|
||||||
for (JsonElement acceptItem : accepts.getAsJsonArray()) {
|
|
||||||
String termUrl = acceptItem.getAsString();
|
|
||||||
LOGGER.info("User {} accepts the term: {}", account.getUserId(), termUrl);
|
|
||||||
accountManager.acceptTerm(token, termUrl);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String termUrl = accepts.getAsString();
|
|
||||||
LOGGER.info("User {} accepts the term: {}", account.getUserId(), termUrl);
|
|
||||||
accountManager.acceptTerm(token, termUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
respondJson(exchange, "{}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package io.kamax.mxisd.http.undertow.handler.term.v2;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class GetTermsHandler extends BasicHttpHandler {
|
|
||||||
|
|
||||||
public static final String PATH = "/_matrix/identity/v2/terms";
|
|
||||||
|
|
||||||
private final JsonObject policyResponse;
|
|
||||||
|
|
||||||
public GetTermsHandler(PolicyConfig config) {
|
|
||||||
policyResponse = new JsonObject();
|
|
||||||
JsonObject policies = new JsonObject();
|
|
||||||
for (Map.Entry<String, PolicyConfig.PolicyObject> policyItem : config.getPolicies().entrySet()) {
|
|
||||||
JsonObject policy = new JsonObject();
|
|
||||||
policy.addProperty("version", policyItem.getValue().getVersion());
|
|
||||||
for (Map.Entry<String, PolicyConfig.TermObject> termEntry : policyItem.getValue().getTerms().entrySet()) {
|
|
||||||
JsonObject term = new JsonObject();
|
|
||||||
term.addProperty("name", termEntry.getValue().getName());
|
|
||||||
term.addProperty("url", termEntry.getValue().getUrl());
|
|
||||||
policy.add(termEntry.getKey(), term);
|
|
||||||
}
|
|
||||||
policies.add(policyItem.getKey(), policy);
|
|
||||||
}
|
|
||||||
policyResponse.add("policies", policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
respond(exchange, policyResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package io.kamax.mxisd.lookup;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HashLookupRequest extends ALookupRequest {
|
|
||||||
|
|
||||||
private List<String> hashes;
|
|
||||||
|
|
||||||
public List<String> getHashes() {
|
|
||||||
return hashes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHashes(List<String> hashes) {
|
|
||||||
this.hashes = hashes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,6 @@ import io.kamax.mxisd.lookup.SingleLookupReply;
|
|||||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -41,7 +40,4 @@ public interface IThreePidProvider {
|
|||||||
|
|
||||||
List<ThreePidMapping> populate(List<ThreePidMapping> mappings);
|
List<ThreePidMapping> populate(List<ThreePidMapping> mappings);
|
||||||
|
|
||||||
default Iterable<ThreePidMapping> populateHashes() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
package io.kamax.mxisd.lookup.strategy;
|
package io.kamax.mxisd.lookup.strategy;
|
||||||
|
|
||||||
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
||||||
import io.kamax.mxisd.lookup.HashLookupRequest;
|
|
||||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||||
@@ -47,5 +46,4 @@ public interface LookupStrategy {
|
|||||||
|
|
||||||
CompletableFuture<List<ThreePidMapping>> find(BulkLookupRequest requests);
|
CompletableFuture<List<ThreePidMapping>> find(BulkLookupRequest requests);
|
||||||
|
|
||||||
CompletableFuture<List<ThreePidMapping>> find(HashLookupRequest request);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,10 @@ import io.kamax.matrix.json.GsonUtil;
|
|||||||
import io.kamax.matrix.json.MatrixJson;
|
import io.kamax.matrix.json.MatrixJson;
|
||||||
import io.kamax.mxisd.config.MxisdConfig;
|
import io.kamax.mxisd.config.MxisdConfig;
|
||||||
import io.kamax.mxisd.exception.ConfigurationException;
|
import io.kamax.mxisd.exception.ConfigurationException;
|
||||||
import io.kamax.mxisd.hash.HashManager;
|
|
||||||
import io.kamax.mxisd.hash.storage.HashStorage;
|
|
||||||
import io.kamax.mxisd.lookup.*;
|
import io.kamax.mxisd.lookup.*;
|
||||||
import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher;
|
import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher;
|
||||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -53,14 +50,10 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
|
|||||||
|
|
||||||
private List<CIDRUtils> allowedCidr = new ArrayList<>();
|
private List<CIDRUtils> allowedCidr = new ArrayList<>();
|
||||||
|
|
||||||
private HashManager hashManager;
|
public RecursivePriorityLookupStrategy(MxisdConfig.Lookup cfg, List<? extends IThreePidProvider> providers, IBridgeFetcher bridge) {
|
||||||
|
|
||||||
public RecursivePriorityLookupStrategy(MxisdConfig.Lookup cfg, List<? extends IThreePidProvider> providers, IBridgeFetcher bridge,
|
|
||||||
HashManager hashManager) {
|
|
||||||
this.cfg = cfg;
|
this.cfg = cfg;
|
||||||
this.bridge = bridge;
|
this.bridge = bridge;
|
||||||
this.providers = new ArrayList<>(providers);
|
this.providers = new ArrayList<>(providers);
|
||||||
this.hashManager = hashManager;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.info("Found {} providers", providers.size());
|
log.info("Found {} providers", providers.size());
|
||||||
@@ -72,8 +65,6 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
|
|||||||
log.info("{} is allowed for recursion", cidr);
|
log.info("{} is allowed for recursion", cidr);
|
||||||
allowedCidr.add(new CIDRUtils(cidr));
|
allowedCidr.add(new CIDRUtils(cidr));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Hash lookups enabled: {}", hashManager.getConfig().isEnabled());
|
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
throw new ConfigurationException("lookup.recursive.allowedCidrs", "Allowed CIDRs");
|
throw new ConfigurationException("lookup.recursive.allowedCidrs", "Allowed CIDRs");
|
||||||
}
|
}
|
||||||
@@ -239,12 +230,4 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
|
|||||||
return bulkLookupInProgress.remove(payloadId);
|
return bulkLookupInProgress.remove(payloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<List<ThreePidMapping>> find(HashLookupRequest request) {
|
|
||||||
HashStorage hashStorage = hashManager.getHashStorage();
|
|
||||||
CompletableFuture<List<ThreePidMapping>> result = new CompletableFuture<>();
|
|
||||||
result.complete(hashStorage.find(request.getHashes()).stream().map(Pair::getValue).collect(Collectors.toList()));
|
|
||||||
hashManager.getRotationStrategy().newRequest();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package io.kamax.mxisd.matrix;
|
|
||||||
|
|
||||||
public enum IdentityServiceAPI {
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
V1,
|
|
||||||
|
|
||||||
V2
|
|
||||||
}
|
|
||||||
@@ -57,8 +57,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@@ -236,19 +235,9 @@ public class SessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.info("Unbinding of {} {} to {} is accepted", tpid.getMedium(), tpid.getAddress(), mxid.getId());
|
log.info("Unbinding of {} {} to {} is accepted", tpid.getMedium(), tpid.getAddress(), mxid.getId());
|
||||||
|
if (cfg.getSession().getPolicy().getUnbind().shouldNotify()) {
|
||||||
notifMgr.sendForUnbind(tpid);
|
notifMgr.sendForUnbind(tpid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDomain(String publicUrl) {
|
|
||||||
URL url;
|
|
||||||
try {
|
|
||||||
url = new URL(publicUrl);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
log.error("Malformed public url, use as is");
|
|
||||||
return publicUrl;
|
|
||||||
}
|
|
||||||
int port = url.getPort();
|
|
||||||
return url.getHost() + (port != -1 ? ":" + url.getPort() : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAuthorization(String auth, JsonObject reqData) {
|
private void checkAuthorization(String auth, JsonObject reqData) {
|
||||||
@@ -256,9 +245,7 @@ public class SessionManager {
|
|||||||
throw new NotAllowedException("Wrong authorization header");
|
throw new NotAllowedException("Wrong authorization header");
|
||||||
}
|
}
|
||||||
|
|
||||||
String domain = getDomain(cfg.getServer().getPublicUrl());
|
if (StringUtils.isBlank(cfg.getServer().getPublicUrl())) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(domain)) {
|
|
||||||
throw new NotAllowedException("Unable to verify request, missing `server.publicUrl` property");
|
throw new NotAllowedException("Unable to verify request, missing `server.publicUrl` property");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +287,7 @@ public class SessionManager {
|
|||||||
jsonObject.addProperty("method", "POST");
|
jsonObject.addProperty("method", "POST");
|
||||||
jsonObject.addProperty("uri", "/_matrix/identity/api/v1/3pid/unbind");
|
jsonObject.addProperty("uri", "/_matrix/identity/api/v1/3pid/unbind");
|
||||||
jsonObject.addProperty("origin", origin);
|
jsonObject.addProperty("origin", origin);
|
||||||
jsonObject.addProperty("destination_is", domain);
|
jsonObject.addProperty("destination_is", URI.create(cfg.getServer().getPublicUrl()).getHost());
|
||||||
jsonObject.add("content", reqData);
|
jsonObject.add("content", reqData);
|
||||||
|
|
||||||
String canonical = MatrixJson.encodeCanonical(jsonObject);
|
String canonical = MatrixJson.encodeCanonical(jsonObject);
|
||||||
|
|||||||
@@ -21,18 +21,13 @@
|
|||||||
package io.kamax.mxisd.storage;
|
package io.kamax.mxisd.storage;
|
||||||
|
|
||||||
import io.kamax.matrix.ThreePid;
|
import io.kamax.matrix.ThreePid;
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
|
import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao;
|
import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO;
|
import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface IStorage {
|
public interface IStorage {
|
||||||
@@ -57,21 +52,4 @@ public interface IStorage {
|
|||||||
|
|
||||||
Optional<ASTransactionDao> getTransactionResult(String localpart, String txnId);
|
Optional<ASTransactionDao> getTransactionResult(String localpart, String txnId);
|
||||||
|
|
||||||
void insertToken(AccountDao accountDao);
|
|
||||||
|
|
||||||
Optional<AccountDao> findAccount(String token);
|
|
||||||
|
|
||||||
void deleteToken(String token);
|
|
||||||
|
|
||||||
void acceptTerm(String token, String url);
|
|
||||||
|
|
||||||
void deleteAccepts(String token);
|
|
||||||
|
|
||||||
boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies);
|
|
||||||
|
|
||||||
void clearHashes();
|
|
||||||
|
|
||||||
void addHash(String mxid, String medium, String address, String hash);
|
|
||||||
|
|
||||||
Collection<Pair<String, ThreePidMapping>> findHashes(Iterable<String> hashes);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,38 +24,25 @@ import com.j256.ormlite.dao.CloseableWrappedIterable;
|
|||||||
import com.j256.ormlite.dao.Dao;
|
import com.j256.ormlite.dao.Dao;
|
||||||
import com.j256.ormlite.dao.DaoManager;
|
import com.j256.ormlite.dao.DaoManager;
|
||||||
import com.j256.ormlite.jdbc.JdbcConnectionSource;
|
import com.j256.ormlite.jdbc.JdbcConnectionSource;
|
||||||
import com.j256.ormlite.stmt.QueryBuilder;
|
|
||||||
import com.j256.ormlite.support.ConnectionSource;
|
import com.j256.ormlite.support.ConnectionSource;
|
||||||
import com.j256.ormlite.table.TableUtils;
|
import com.j256.ormlite.table.TableUtils;
|
||||||
import io.kamax.matrix.ThreePid;
|
import io.kamax.matrix.ThreePid;
|
||||||
import io.kamax.mxisd.config.MxisdConfig;
|
import io.kamax.mxisd.config.MxisdConfig;
|
||||||
import io.kamax.mxisd.config.PolicyConfig;
|
|
||||||
import io.kamax.mxisd.exception.ConfigurationException;
|
import io.kamax.mxisd.exception.ConfigurationException;
|
||||||
import io.kamax.mxisd.exception.InternalServerError;
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
|
||||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
|
||||||
import io.kamax.mxisd.storage.IStorage;
|
import io.kamax.mxisd.storage.IStorage;
|
||||||
import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
|
import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao;
|
import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AccountDao;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.HashDao;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.HistoricalThreePidInviteIO;
|
import io.kamax.mxisd.storage.ormlite.dao.HistoricalThreePidInviteIO;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.AcceptedDao;
|
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO;
|
import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO;
|
||||||
import io.kamax.mxisd.storage.ormlite.dao.ThreePidSessionDao;
|
import io.kamax.mxisd.storage.ormlite.dao.ThreePidSessionDao;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class OrmLiteSqlStorage implements IStorage {
|
public class OrmLiteSqlStorage implements IStorage {
|
||||||
|
|
||||||
@@ -77,9 +64,6 @@ public class OrmLiteSqlStorage implements IStorage {
|
|||||||
private Dao<HistoricalThreePidInviteIO, String> expInvDao;
|
private Dao<HistoricalThreePidInviteIO, String> expInvDao;
|
||||||
private Dao<ThreePidSessionDao, String> sessionDao;
|
private Dao<ThreePidSessionDao, String> sessionDao;
|
||||||
private Dao<ASTransactionDao, String> asTxnDao;
|
private Dao<ASTransactionDao, String> asTxnDao;
|
||||||
private Dao<AccountDao, String> accountDao;
|
|
||||||
private Dao<AcceptedDao, String> acceptedDao;
|
|
||||||
private Dao<HashDao, String> hashDao;
|
|
||||||
|
|
||||||
public OrmLiteSqlStorage(MxisdConfig cfg) {
|
public OrmLiteSqlStorage(MxisdConfig cfg) {
|
||||||
this(cfg.getStorage().getBackend(), cfg.getStorage().getProvider().getSqlite().getDatabase());
|
this(cfg.getStorage().getBackend(), cfg.getStorage().getProvider().getSqlite().getDatabase());
|
||||||
@@ -100,9 +84,6 @@ public class OrmLiteSqlStorage implements IStorage {
|
|||||||
expInvDao = createDaoAndTable(connPool, HistoricalThreePidInviteIO.class);
|
expInvDao = createDaoAndTable(connPool, HistoricalThreePidInviteIO.class);
|
||||||
sessionDao = createDaoAndTable(connPool, ThreePidSessionDao.class);
|
sessionDao = createDaoAndTable(connPool, ThreePidSessionDao.class);
|
||||||
asTxnDao = createDaoAndTable(connPool, ASTransactionDao.class);
|
asTxnDao = createDaoAndTable(connPool, ASTransactionDao.class);
|
||||||
accountDao = createDaoAndTable(connPool, AccountDao.class);
|
|
||||||
acceptedDao = createDaoAndTable(connPool, AcceptedDao.class);
|
|
||||||
hashDao = createDaoAndTable(connPool, HashDao.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,103 +237,4 @@ public class OrmLiteSqlStorage implements IStorage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void insertToken(AccountDao account) {
|
|
||||||
withCatcher(() -> {
|
|
||||||
int created = accountDao.create(account);
|
|
||||||
if (created != 1) {
|
|
||||||
throw new RuntimeException("Unexpected row count after DB action: " + created);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<AccountDao> findAccount(String token) {
|
|
||||||
return withCatcher(() -> {
|
|
||||||
List<AccountDao> accounts = accountDao.queryForEq("token", token);
|
|
||||||
if (accounts.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (accounts.size() != 1) {
|
|
||||||
throw new RuntimeException("Unexpected rows for access token: " + accounts.size());
|
|
||||||
}
|
|
||||||
return Optional.of(accounts.get(0));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteToken(String token) {
|
|
||||||
withCatcher(() -> {
|
|
||||||
int updated = accountDao.deleteById(token);
|
|
||||||
if (updated != 1) {
|
|
||||||
throw new RuntimeException("Unexpected row count after DB action: " + updated);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acceptTerm(String token, String url) {
|
|
||||||
withCatcher(() -> {
|
|
||||||
AccountDao account = findAccount(token).orElseThrow(InvalidCredentialsException::new);
|
|
||||||
int created = acceptedDao.create(new AcceptedDao(url, account.getUserId(), System.currentTimeMillis()));
|
|
||||||
if (created != 1) {
|
|
||||||
throw new RuntimeException("Unexpected row count after DB action: " + created);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteAccepts(String token) {
|
|
||||||
withCatcher(() -> {
|
|
||||||
AccountDao account = findAccount(token).orElseThrow(InvalidCredentialsException::new);
|
|
||||||
acceptedDao.delete(acceptedDao.queryForEq("userId", account.getUserId()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies) {
|
|
||||||
return withCatcher(() -> {
|
|
||||||
AccountDao account = findAccount(token).orElseThrow(InvalidCredentialsException::new);
|
|
||||||
List<AcceptedDao> acceptedTerms = acceptedDao.queryForEq("userId", account.getUserId());
|
|
||||||
for (AcceptedDao acceptedTerm : acceptedTerms) {
|
|
||||||
for (PolicyConfig.PolicyObject policy : policies) {
|
|
||||||
for (PolicyConfig.TermObject termObject : policy.getTerms().values()) {
|
|
||||||
if (termObject.getUrl().equalsIgnoreCase(acceptedTerm.getUrl())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearHashes() {
|
|
||||||
withCatcher(() -> {
|
|
||||||
List<HashDao> allHashes = hashDao.queryForAll();
|
|
||||||
int deleted = hashDao.delete(allHashes);
|
|
||||||
if (deleted != allHashes.size()) {
|
|
||||||
throw new RuntimeException("Not all hashes deleted: " + deleted);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addHash(String mxid, String medium, String address, String hash) {
|
|
||||||
withCatcher(() -> {
|
|
||||||
hashDao.create(new HashDao(mxid, medium, address, hash));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Pair<String, ThreePidMapping>> findHashes(Iterable<String> hashes) {
|
|
||||||
return withCatcher(() -> {
|
|
||||||
QueryBuilder<HashDao, String> builder = hashDao.queryBuilder();
|
|
||||||
builder.where().in("hash", hashes);
|
|
||||||
return hashDao.query(builder.prepare()).stream()
|
|
||||||
.map(dao -> Pair.of(dao.getHash(), new ThreePidMapping(dao.getMedium(), dao.getAddress(), dao.getMxid()))).collect(
|
|
||||||
Collectors.toList());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.storage.ormlite.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "accepted")
|
|
||||||
public class AcceptedDao {
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false, id = true)
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private long acceptedAt;
|
|
||||||
|
|
||||||
public AcceptedDao() {
|
|
||||||
// Needed for ORMLite
|
|
||||||
}
|
|
||||||
|
|
||||||
public AcceptedDao(String url, String userId, long acceptedAt) {
|
|
||||||
this.url = url;
|
|
||||||
this.userId = userId;
|
|
||||||
this.acceptedAt = acceptedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId() {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(String userId) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getAcceptedAt() {
|
|
||||||
return acceptedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAcceptedAt(long acceptedAt) {
|
|
||||||
this.acceptedAt = acceptedAt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,119 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.kamax.mxisd.storage.ormlite.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "account")
|
|
||||||
public class AccountDao {
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false, id = true)
|
|
||||||
private String token;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String tokenType;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String matrixServerName;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private long expiresIn;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private long createdAt;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
public AccountDao() {
|
|
||||||
// Needed for ORMLite
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountDao(String accessToken, String tokenType, String matrixServerName, long expiresIn, long createdAt, String userId, String token) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
this.tokenType = tokenType;
|
|
||||||
this.matrixServerName = matrixServerName;
|
|
||||||
this.expiresIn = expiresIn;
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
this.userId = userId;
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTokenType() {
|
|
||||||
return tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTokenType(String tokenType) {
|
|
||||||
this.tokenType = tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMatrixServerName() {
|
|
||||||
return matrixServerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMatrixServerName(String matrixServerName) {
|
|
||||||
this.matrixServerName = matrixServerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getExpiresIn() {
|
|
||||||
return expiresIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpiresIn(long expiresIn) {
|
|
||||||
this.expiresIn = expiresIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCreatedAt() {
|
|
||||||
return createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedAt(long createdAt) {
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId() {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(String userId) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getToken() {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToken(String token) {
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package io.kamax.mxisd.storage.ormlite.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "hashes")
|
|
||||||
public class HashDao {
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false, id = true)
|
|
||||||
private String mxid;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String medium;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String address;
|
|
||||||
|
|
||||||
@DatabaseField(canBeNull = false)
|
|
||||||
private String hash;
|
|
||||||
|
|
||||||
public HashDao() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashDao(String mxid, String medium, String address, String hash) {
|
|
||||||
this.mxid = mxid;
|
|
||||||
this.medium = medium;
|
|
||||||
this.address = address;
|
|
||||||
this.hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMxid() {
|
|
||||||
return mxid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMxid(String mxid) {
|
|
||||||
this.mxid = mxid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMedium() {
|
|
||||||
return medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMedium(String medium) {
|
|
||||||
this.medium = medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddress(String address) {
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHash() {
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHash(String hash) {
|
|
||||||
this.hash = hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user