Add the hash lookup handler.

This commit is contained in:
Anatoly Sablin
2019-10-18 22:52:13 +03:00
parent a0270c7d01
commit 43fe8b1aec
15 changed files with 324 additions and 16 deletions

View File

@@ -0,0 +1,33 @@
/*
* 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;
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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;
}
}

View File

@@ -87,6 +87,10 @@ public class SaneHandler extends BasicHttpHandler {
respond(exchange, HttpStatus.SC_NOT_FOUND, "M_NOT_FOUND", e.getMessage());
} catch (NotImplementedException e) {
respond(exchange, HttpStatus.SC_NOT_IMPLEMENTED, "M_NOT_IMPLEMENTED", e.getMessage());
} catch (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) {
if (StringUtils.isNotBlank(e.getInternalReason())) {
log.error("Feature not available: {}", e.getInternalReason());

View File

@@ -0,0 +1,116 @@
/*
* 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.v1;
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;
}
@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.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 {
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) {
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";
}
}