Bye bye Groovy, you won't be missed :(
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* mxisd - Matrix Identity Server Daemon
|
||||
* Copyright (C) 2017 Maxime Dor
|
||||
*
|
||||
* https://max.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.lookup.strategy;
|
||||
|
||||
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.provider.IThreePidProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface LookupStrategy {
|
||||
|
||||
List<IThreePidProvider> getLocalProviders();
|
||||
|
||||
Optional<SingleLookupReply> find(String medium, String address, boolean recursive);
|
||||
|
||||
Optional<SingleLookupReply> findLocal(String medium, String address);
|
||||
|
||||
Optional<SingleLookupReply> findRemote(String medium, String address);
|
||||
|
||||
Optional<SingleLookupReply> find(SingleLookupRequest request);
|
||||
|
||||
Optional<SingleLookupReply> findRecursive(SingleLookupRequest request);
|
||||
|
||||
List<ThreePidMapping> find(BulkLookupRequest requests);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* mxisd - Matrix Identity Server Daemon
|
||||
* Copyright (C) 2017 Maxime Dor
|
||||
*
|
||||
* https://max.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.lookup.strategy;
|
||||
|
||||
import edazdarevic.commons.net.CIDRUtils;
|
||||
import io.kamax.mxisd.config.RecursiveLookupConfig;
|
||||
import io.kamax.mxisd.exception.ConfigurationException;
|
||||
import io.kamax.mxisd.lookup.*;
|
||||
import io.kamax.mxisd.lookup.fetcher.IBridgeFetcher;
|
||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class RecursivePriorityLookupStrategy implements LookupStrategy {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(RecursivePriorityLookupStrategy.class);
|
||||
|
||||
@Autowired
|
||||
private RecursiveLookupConfig recursiveCfg;
|
||||
|
||||
@Autowired
|
||||
private List<IThreePidProvider> providers;
|
||||
|
||||
@Autowired
|
||||
private IBridgeFetcher bridge;
|
||||
|
||||
private List<CIDRUtils> allowedCidr = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
private void build() throws UnknownHostException {
|
||||
try {
|
||||
log.info("Found {} providers", providers.size());
|
||||
|
||||
providers.sort((o1, o2) -> Integer.compare(o2.getPriority(), o1.getPriority()));
|
||||
|
||||
log.info("Recursive lookup enabled: {}", recursiveCfg.isEnabled());
|
||||
for (String cidr : recursiveCfg.getAllowedCidr()) {
|
||||
log.info("{} is allowed for recursion", cidr);
|
||||
allowedCidr.add(new CIDRUtils(cidr));
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new ConfigurationException("lookup.recursive.allowedCidrs", "Allowed CIDRs");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAllowedForRecursive(String source) {
|
||||
boolean canRecurse = false;
|
||||
|
||||
try {
|
||||
if (recursiveCfg.isEnabled()) {
|
||||
log.debug("Checking {} CIDRs for recursion", allowedCidr.size());
|
||||
for (CIDRUtils cidr : allowedCidr) {
|
||||
if (cidr.isInRange(source)) {
|
||||
log.debug("{} is in range {}, allowing recursion", source, cidr.getNetworkAddress());
|
||||
canRecurse = true;
|
||||
break;
|
||||
} else {
|
||||
log.debug("{} is not in range {}", source, cidr.getNetworkAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
// this should never happened as we should have only IP ranges!
|
||||
log.error("Unexpected {} exception: {}", e.getClass().getSimpleName(), e.getMessage());
|
||||
}
|
||||
|
||||
return canRecurse;
|
||||
}
|
||||
|
||||
private List<IThreePidProvider> listUsableProviders(ALookupRequest request) {
|
||||
return listUsableProviders(request, false);
|
||||
}
|
||||
|
||||
private List<IThreePidProvider> listUsableProviders(ALookupRequest request, boolean forceRecursive) {
|
||||
List<IThreePidProvider> usableProviders = new ArrayList<>();
|
||||
|
||||
boolean canRecurse = forceRecursive || isAllowedForRecursive(request.getRequester());
|
||||
|
||||
log.info("Host {} allowed for recursion: {}", request.getRequester(), canRecurse);
|
||||
for (IThreePidProvider provider : providers) {
|
||||
if (provider.isEnabled() && (provider.isLocal() || canRecurse || forceRecursive)) {
|
||||
usableProviders.add(provider);
|
||||
}
|
||||
}
|
||||
|
||||
return usableProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IThreePidProvider> getLocalProviders() {
|
||||
return providers.stream().filter(iThreePidProvider -> iThreePidProvider.isEnabled() && iThreePidProvider.isLocal()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<IThreePidProvider> getRemoteProviders() {
|
||||
return providers.stream().filter(iThreePidProvider -> iThreePidProvider.isEnabled() && !iThreePidProvider.isLocal()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static SingleLookupRequest build(String medium, String address) {
|
||||
SingleLookupRequest req = new SingleLookupRequest();
|
||||
req.setType(medium);
|
||||
req.setThreePid(address);
|
||||
req.setRequester("Internal");
|
||||
return req;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> find(String medium, String address, boolean recursive) {
|
||||
return find(build(medium, address), recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> findLocal(String medium, String address) {
|
||||
return find(build(medium, address), getLocalProviders());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> findRemote(String medium, String address) {
|
||||
return find(build(medium, address), getRemoteProviders());
|
||||
}
|
||||
|
||||
public Optional<SingleLookupReply> find(SingleLookupRequest request, boolean forceRecursive) {
|
||||
return find(request, listUsableProviders(request, forceRecursive));
|
||||
}
|
||||
|
||||
public Optional<SingleLookupReply> find(SingleLookupRequest request, List<IThreePidProvider> providers) {
|
||||
for (IThreePidProvider provider : providers) {
|
||||
Optional<SingleLookupReply> lookupDataOpt = provider.find(request);
|
||||
if (lookupDataOpt.isPresent()) {
|
||||
return lookupDataOpt;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
recursiveCfg.getBridge() != null &&
|
||||
recursiveCfg.getBridge().getEnabled() &&
|
||||
(!recursiveCfg.getBridge().getRecursiveOnly() || isAllowedForRecursive(request.getRequester()))
|
||||
) {
|
||||
log.info("Using bridge failover for lookup");
|
||||
return bridge.find(request);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> find(SingleLookupRequest request) {
|
||||
return find(request, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> findRecursive(SingleLookupRequest request) {
|
||||
return find(request, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThreePidMapping> find(BulkLookupRequest request) {
|
||||
List<ThreePidMapping> mapToDo = new ArrayList<>(request.getMappings());
|
||||
List<ThreePidMapping> mapFoundAll = new ArrayList<>();
|
||||
|
||||
for (IThreePidProvider provider : listUsableProviders(request)) {
|
||||
if (mapToDo.isEmpty()) {
|
||||
log.info("No more mappings to lookup");
|
||||
break;
|
||||
} else {
|
||||
log.info("{} mappings remaining overall", mapToDo.size());
|
||||
}
|
||||
|
||||
log.info("Using provider {} for remaining mappings", provider.getClass().getSimpleName());
|
||||
List<ThreePidMapping> mapFound = provider.populate(mapToDo);
|
||||
log.info("Provider {} returned {} mappings", provider.getClass().getSimpleName(), mapFound.size());
|
||||
mapFoundAll.addAll(mapFound);
|
||||
mapToDo.removeAll(mapFound);
|
||||
}
|
||||
|
||||
return mapFoundAll;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user