Add the TOS API.
This commit is contained in:
@@ -59,6 +59,8 @@ 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.kamax.mxisd.matrix.IdentityServiceAPI;
|
||||||
import io.undertow.Handlers;
|
import io.undertow.Handlers;
|
||||||
import io.undertow.Undertow;
|
import io.undertow.Undertow;
|
||||||
@@ -66,6 +68,7 @@ import io.undertow.server.HttpHandler;
|
|||||||
import io.undertow.server.RoutingHandler;
|
import io.undertow.server.RoutingHandler;
|
||||||
import io.undertow.util.HttpString;
|
import io.undertow.util.HttpString;
|
||||||
import io.undertow.util.Methods;
|
import io.undertow.util.Methods;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -143,6 +146,7 @@ public class HttpMxisd {
|
|||||||
.get(InternalInfoHandler.Path, SaneHandler.around(new InternalInfoHandler()));
|
.get(InternalInfoHandler.Path, SaneHandler.around(new InternalInfoHandler()));
|
||||||
keyEndpoints(handler);
|
keyEndpoints(handler);
|
||||||
identityEndpoints(handler);
|
identityEndpoints(handler);
|
||||||
|
termsEndpoints(handler);
|
||||||
httpSrv = Undertow.builder().addHttpListener(m.getConfig().getServer().getPort(), "0.0.0.0").setHandler(handler).build();
|
httpSrv = Undertow.builder().addHttpListener(m.getConfig().getServer().getPort(), "0.0.0.0").setHandler(handler).build();
|
||||||
|
|
||||||
httpSrv.start();
|
httpSrv.start();
|
||||||
@@ -186,6 +190,12 @@ public class HttpMxisd {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 addEndpoints(RoutingHandler routingHandler, HttpString method, boolean useAuthorization, ApiHandler... handlers) {
|
private void addEndpoints(RoutingHandler routingHandler, HttpString method, boolean useAuthorization, ApiHandler... handlers) {
|
||||||
for (ApiHandler handler : handlers) {
|
for (ApiHandler handler : handlers) {
|
||||||
attachHandler(routingHandler, method, handler, useAuthorization, sane(handler));
|
attachHandler(routingHandler, method, handler, useAuthorization, sane(handler));
|
||||||
@@ -199,23 +209,28 @@ public class HttpMxisd {
|
|||||||
routingHandler.add(method, apiHandler.getPath(IdentityServiceAPI.V1), httpHandler);
|
routingHandler.add(method, apiHandler.getPath(IdentityServiceAPI.V1), httpHandler);
|
||||||
}
|
}
|
||||||
if (matrixConfig.isV2()) {
|
if (matrixConfig.isV2()) {
|
||||||
PolicyConfig policyConfig = m.getConfig().getPolicy();
|
HttpHandler handlerWithTerms = CheckTermsHandler.around(m.getAccMgr(), httpHandler, getPolicyObjects(apiHandler));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HttpHandler handlerWithTerms = CheckTermsHandler.around(m.getAccMgr(), httpHandler, policies);
|
|
||||||
HttpHandler wrappedHandler = useAuthorization ? AuthorizationHandler.around(m.getAccMgr(), handlerWithTerms) : handlerWithTerms;
|
HttpHandler wrappedHandler = useAuthorization ? AuthorizationHandler.around(m.getAccMgr(), handlerWithTerms) : handlerWithTerms;
|
||||||
routingHandler.add(method, apiHandler.getPath(IdentityServiceAPI.V2), wrappedHandler);
|
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) {
|
private HttpHandler sane(HttpHandler httpHandler) {
|
||||||
return SaneHandler.around(httpHandler);
|
return SaneHandler.around(httpHandler);
|
||||||
}
|
}
|
||||||
|
@@ -138,6 +138,7 @@ public class AccountManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAccount(String token) {
|
public void deleteAccount(String token) {
|
||||||
|
storage.deleteAccepts(token);
|
||||||
storage.deleteToken(token);
|
storage.deleteToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
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, "{}");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,37 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -63,5 +63,7 @@ public interface IStorage {
|
|||||||
|
|
||||||
void acceptTerm(String token, String url);
|
void acceptTerm(String token, String url);
|
||||||
|
|
||||||
|
void deleteAccepts(String token);
|
||||||
|
|
||||||
boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies);
|
boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies);
|
||||||
}
|
}
|
||||||
|
@@ -294,6 +294,14 @@ public class OrmLiteSqlStorage implements IStorage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAccepts(String token) {
|
||||||
|
withCatcher(() -> {
|
||||||
|
AccountDao account = findAccount(token).orElseThrow(InvalidCredentialsException::new);
|
||||||
|
acceptedDao.delete(acceptedDao.queryForEq("userId", account.getUserId()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies) {
|
public boolean isTermAccepted(String token, List<PolicyConfig.PolicyObject> policies) {
|
||||||
return withCatcher(() -> {
|
return withCatcher(() -> {
|
||||||
|
Reference in New Issue
Block a user