Add support of the MSC2134 (Identity hash lookup) for the LDAP provider.
This commit is contained in:
@@ -108,7 +108,7 @@ dependencies {
|
||||
compile 'net.i2p.crypto:eddsa:0.3.0'
|
||||
|
||||
// LDAP connector
|
||||
compile 'org.apache.directory.api:api-all:1.0.0'
|
||||
compile 'org.apache.directory.api:api-all:1.0.3'
|
||||
|
||||
// DNS lookups
|
||||
compile 'dnsjava:dnsjava:2.1.9'
|
||||
|
@@ -89,7 +89,7 @@ ldap:
|
||||
#### 3PIDs
|
||||
You can also change the attribute lists for 3PID, like email or phone numbers.
|
||||
|
||||
The following example would overwrite the [default list of attributes](../../src/main/java/io/kamax/ma1sd/config/ldap/LdapConfig.java#L64)
|
||||
The following example would overwrite the [default list of attributes](../../src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java#L64)
|
||||
for emails and phone number:
|
||||
```yaml
|
||||
ldap:
|
||||
|
@@ -41,7 +41,10 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LdapThreePidProvider extends LdapBackend implements IThreePidProvider {
|
||||
|
||||
@@ -137,4 +140,61 @@ public class LdapThreePidProvider extends LdapBackend implements IThreePidProvid
|
||||
return mappingsFound;
|
||||
}
|
||||
|
||||
private List<String> getAttributes() {
|
||||
final List<String> attributes = getCfg().getAttribute().getThreepid().values().stream().flatMap(List::stream)
|
||||
.collect(Collectors.toList());
|
||||
attributes.add(getUidAtt());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private Optional<String> getAttributeValue(Entry entry, List<String> attributes) {
|
||||
return attributes.stream()
|
||||
.map(attr -> getAttribute(entry, attr))
|
||||
.filter(Objects::nonNull)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ThreePidMapping> populateHashes() {
|
||||
List<ThreePidMapping> result = new ArrayList<>();
|
||||
String filter = getCfg().getIdentity().getFilter();
|
||||
|
||||
try (LdapConnection conn = getConn()) {
|
||||
bind(conn);
|
||||
|
||||
log.debug("Query: {}", filter);
|
||||
List<String> attributes = getAttributes();
|
||||
log.debug("Attributes: {}", GsonUtil.build().toJson(attributes));
|
||||
|
||||
for (String baseDN : getBaseDNs()) {
|
||||
log.debug("Base DN: {}", baseDN);
|
||||
|
||||
try (EntryCursor cursor = conn.search(baseDN, filter, SearchScope.SUBTREE, attributes.toArray(new String[0]))) {
|
||||
while (cursor.next()) {
|
||||
Entry entry = cursor.get();
|
||||
log.info("Found possible match, DN: {}", entry.getDn().getName());
|
||||
Optional<String> mxid = getAttribute(entry, getUidAtt());
|
||||
if (!mxid.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<String>> attributeEntry : getCfg().getAttribute().getThreepid().entrySet()) {
|
||||
String medium = attributeEntry.getKey();
|
||||
getAttributeValue(entry, attributeEntry.getValue())
|
||||
.ifPresent(s -> result.add(new ThreePidMapping(medium, s, buildMatrixIdFromUid(mxid.get()))));
|
||||
}
|
||||
}
|
||||
} catch (CursorLdapReferralException e) {
|
||||
log.warn("3PID is only available via referral, skipping", e);
|
||||
} catch (IOException | LdapException | CursorException e) {
|
||||
log.error("Unable to fetch 3PID mappings", e);
|
||||
}
|
||||
}
|
||||
} catch (LdapException | IOException e) {
|
||||
log.error("Unable to fetch 3PID mappings", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -107,14 +107,16 @@ public abstract class SqlThreePidProvider implements IThreePidProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<ThreePidMapping> populateHashes() {
|
||||
if (StringUtils.isBlank(cfg.getLookup().getQuery())) {
|
||||
String query = cfg.getLookup().getQuery();
|
||||
if (StringUtils.isBlank(query)) {
|
||||
log.warn("Lookup query not configured, skip.");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
log.debug("Uses query to match users: {}", query);
|
||||
List<ThreePidMapping> result = new ArrayList<>();
|
||||
try (Connection connection = pool.get()) {
|
||||
PreparedStatement statement = connection.prepareStatement(cfg.getLookup().getQuery());
|
||||
PreparedStatement statement = connection.prepareStatement(query);
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
String mxid = resultSet.getString("mxid");
|
||||
|
@@ -35,7 +35,9 @@ public class HashEngine {
|
||||
hashStorage.clear();
|
||||
for (IThreePidProvider provider : providers) {
|
||||
try {
|
||||
LOGGER.info("Populate hashes from the handler: {}", provider.getClass().getCanonicalName());
|
||||
for (ThreePidMapping pidMapping : provider.populateHashes()) {
|
||||
LOGGER.debug("Found 3PID: {}", pidMapping);
|
||||
hashStorage.add(pidMapping, hash(pidMapping));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@@ -85,6 +85,7 @@ public class HashLookupHandler extends LookupHandler implements ApiHandler {
|
||||
default:
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
hashManager.getRotationStrategy().newRequest();
|
||||
}
|
||||
|
||||
private void noneAlgorithm(HttpServerExchange exchange, HashLookupRequest request, ClientHashLookupRequest input) throws Exception {
|
||||
|
@@ -46,6 +46,4 @@ public interface LookupStrategy {
|
||||
Optional<SingleLookupReply> findRecursive(SingleLookupRequest request);
|
||||
|
||||
CompletableFuture<List<ThreePidMapping>> find(BulkLookupRequest requests);
|
||||
|
||||
CompletableFuture<List<ThreePidMapping>> find(HashLookupRequest request);
|
||||
}
|
||||
|
@@ -26,17 +26,23 @@ import io.kamax.matrix.json.MatrixJson;
|
||||
import io.kamax.mxisd.config.MxisdConfig;
|
||||
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.ALookupRequest;
|
||||
import io.kamax.mxisd.lookup.BulkLookupRequest;
|
||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||
import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher;
|
||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -238,13 +244,4 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
|
||||
result.complete(mapFoundAll);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user