Refactor logic, preparing to generalize post-login publish of mappings
This commit is contained in:
@@ -39,4 +39,9 @@ public class ThreePid {
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getMedium() + ":" + getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd.auth;
|
package io.kamax.mxisd.auth;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.ThreePid;
|
||||||
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
||||||
|
import io.kamax.mxisd.invitation.InvitationManager;
|
||||||
|
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -37,6 +40,9 @@ public class AuthManager {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private List<AuthenticatorProvider> providers = new ArrayList<>();
|
private List<AuthenticatorProvider> providers = new ArrayList<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InvitationManager invMgr;
|
||||||
|
|
||||||
public UserAuthResult authenticate(String id, String password) {
|
public UserAuthResult authenticate(String id, String password) {
|
||||||
for (AuthenticatorProvider provider : providers) {
|
for (AuthenticatorProvider provider : providers) {
|
||||||
if (!provider.isEnabled()) {
|
if (!provider.isEnabled()) {
|
||||||
@@ -45,6 +51,12 @@ public class AuthManager {
|
|||||||
|
|
||||||
UserAuthResult result = provider.authenticate(id, password);
|
UserAuthResult result = provider.authenticate(id, password);
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
|
log.info("{} was authenticated by {}, publishing 3PID mappings, if any", id, provider.getClass().getSimpleName());
|
||||||
|
for (ThreePid pid : result.getThreePids()) {
|
||||||
|
log.info("Processing {} for {}", pid, id);
|
||||||
|
invMgr.publishMappingIfInvited(new ThreePidMapping(pid, result.getMxid()));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,19 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd.auth;
|
package io.kamax.mxisd.auth;
|
||||||
|
|
||||||
|
import io.kamax.matrix.ThreePidMedium;
|
||||||
|
import io.kamax.mxisd.ThreePid;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class UserAuthResult {
|
public class UserAuthResult {
|
||||||
|
|
||||||
private boolean success;
|
private boolean success;
|
||||||
private String mxid;
|
private String mxid;
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
private List<ThreePid> threePids = new ArrayList<>();
|
||||||
|
|
||||||
public UserAuthResult failure() {
|
public UserAuthResult failure() {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -66,4 +74,18 @@ public class UserAuthResult {
|
|||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserAuthResult withThreePid(ThreePidMedium medium, String address) {
|
||||||
|
return withThreePid(medium.getId(), address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAuthResult withThreePid(String medium, String address) {
|
||||||
|
threePids.add(new ThreePid(medium, address));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ThreePid> getThreePids() {
|
||||||
|
return Collections.unmodifiableList(threePids);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,17 +22,12 @@ package io.kamax.mxisd.auth.provider
|
|||||||
|
|
||||||
import com.google.firebase.FirebaseApp
|
import com.google.firebase.FirebaseApp
|
||||||
import com.google.firebase.FirebaseOptions
|
import com.google.firebase.FirebaseOptions
|
||||||
import com.google.firebase.auth.FirebaseAuth
|
import com.google.firebase.auth.*
|
||||||
import com.google.firebase.auth.FirebaseCredential
|
|
||||||
import com.google.firebase.auth.FirebaseCredentials
|
|
||||||
import com.google.firebase.auth.FirebaseToken
|
|
||||||
import com.google.firebase.internal.NonNull
|
import com.google.firebase.internal.NonNull
|
||||||
import com.google.firebase.tasks.OnFailureListener
|
import com.google.firebase.tasks.OnFailureListener
|
||||||
import com.google.firebase.tasks.OnSuccessListener
|
import com.google.firebase.tasks.OnSuccessListener
|
||||||
import io.kamax.matrix.ThreePidMedium
|
import io.kamax.matrix.ThreePidMedium
|
||||||
import io.kamax.mxisd.auth.UserAuthResult
|
import io.kamax.mxisd.auth.UserAuthResult
|
||||||
import io.kamax.mxisd.invitation.InvitationManager
|
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping
|
|
||||||
import org.apache.commons.lang.StringUtils
|
import org.apache.commons.lang.StringUtils
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
@@ -46,25 +41,31 @@ public class GoogleFirebaseAuthenticator implements AuthenticatorProvider {
|
|||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger(GoogleFirebaseAuthenticator.class);
|
private Logger log = LoggerFactory.getLogger(GoogleFirebaseAuthenticator.class);
|
||||||
|
|
||||||
private static final Pattern matrixIdLaxPattern = Pattern.compile("@(.*):(.+)");
|
private static final Pattern matrixIdLaxPattern = Pattern.compile("@(.*):(.+)"); // FIXME use matrix-java-sdk
|
||||||
|
|
||||||
private boolean isEnabled;
|
private boolean isEnabled;
|
||||||
private String domain;
|
private String domain;
|
||||||
private FirebaseApp fbApp;
|
private FirebaseApp fbApp;
|
||||||
private FirebaseAuth fbAuth;
|
private FirebaseAuth fbAuth;
|
||||||
|
|
||||||
private InvitationManager invMgr;
|
private void waitOnLatch(UserAuthResult result, CountDownLatch l, long timeout, TimeUnit unit, String purpose) {
|
||||||
|
try {
|
||||||
public GoogleFirebaseAuthenticator(InvitationManager invMgr, boolean isEnabled) {
|
l.await(timeout, unit);
|
||||||
this.isEnabled = isEnabled;
|
} catch (InterruptedException e) {
|
||||||
this.invMgr = invMgr;
|
log.warn("Interrupted while waiting for " + purpose);
|
||||||
|
result.failure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GoogleFirebaseAuthenticator(InvitationManager invMgr, String credsPath, String db, String domain) {
|
public GoogleFirebaseAuthenticator(boolean isEnabled) {
|
||||||
this(invMgr, true);
|
this.isEnabled = isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoogleFirebaseAuthenticator(String credsPath, String db, String domain) {
|
||||||
|
this(true);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
try {
|
try {
|
||||||
fbApp = FirebaseApp.initializeApp(getOpts(credsPath, db));
|
fbApp = FirebaseApp.initializeApp(getOpts(credsPath, db), "AuthenticationProvider");
|
||||||
fbAuth = FirebaseAuth.getInstance(fbApp);
|
fbAuth = FirebaseAuth.getInstance(fbApp);
|
||||||
|
|
||||||
log.info("Google Firebase Authentication is ready");
|
log.info("Google Firebase Authentication is ready");
|
||||||
@@ -130,14 +131,42 @@ public class GoogleFirebaseAuthenticator implements AuthenticatorProvider {
|
|||||||
if (!StringUtils.equals(localpart, token.getUid())) {
|
if (!StringUtils.equals(localpart, token.getUid())) {
|
||||||
log.info("Failture to authenticate {}: Matrix ID localpart '{}' does not match Firebase UID '{}'", id, localpart, token.getUid());
|
log.info("Failture to authenticate {}: Matrix ID localpart '{}' does not match Firebase UID '{}'", id, localpart, token.getUid());
|
||||||
result.failure();
|
result.failure();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("{} was successfully authenticated", id);
|
log.info("{} was successfully authenticated", id);
|
||||||
result.success(id, token.getName());
|
result.success(id, token.getName());
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(token.getEmail())) {
|
log.info("Fetching profile for {}", id);
|
||||||
invMgr.publishMappingIfInvited(new ThreePidMapping(ThreePidMedium.Email.getId(), token.getEmail(), id))
|
CountDownLatch userRecordLatch = new CountDownLatch(1);
|
||||||
|
fbAuth.getUser(token.getUid()).addOnSuccessListener(new OnSuccessListener<UserRecord>() {
|
||||||
|
@Override
|
||||||
|
void onSuccess(UserRecord user) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotBlank(user.getEmail())) {
|
||||||
|
result.withThreePid(ThreePidMedium.Email, user.getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(user.getPhoneNumber())) {
|
||||||
|
result.withThreePid(ThreePidMedium.PhoneNumber, user.getPhoneNumber());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
userRecordLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).addOnFailureListener(new OnFailureListener() {
|
||||||
|
@Override
|
||||||
|
void onFailure(@NonNull Exception e) {
|
||||||
|
try {
|
||||||
|
log.warn("Unable to fetch Firebase user profile for {}", id);
|
||||||
|
result.failure();
|
||||||
|
} finally {
|
||||||
|
userRecordLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
waitOnLatch(result, userRecordLatch, 30, TimeUnit.SECONDS, "Firebase user profile");
|
||||||
} finally {
|
} finally {
|
||||||
l.countDown()
|
l.countDown()
|
||||||
}
|
}
|
||||||
@@ -160,13 +189,7 @@ public class GoogleFirebaseAuthenticator implements AuthenticatorProvider {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
waitOnLatch(result, l, 30, TimeUnit.SECONDS, "Firebase auth check");
|
||||||
l.await(30, TimeUnit.SECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
log.warn("Interrupted while waiting for Firebase auth check");
|
|
||||||
result.failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ package io.kamax.mxisd.config;
|
|||||||
|
|
||||||
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
||||||
import io.kamax.mxisd.auth.provider.GoogleFirebaseAuthenticator;
|
import io.kamax.mxisd.auth.provider.GoogleFirebaseAuthenticator;
|
||||||
import io.kamax.mxisd.invitation.InvitationManager;
|
|
||||||
import io.kamax.mxisd.lookup.provider.GoogleFirebaseProvider;
|
import io.kamax.mxisd.lookup.provider.GoogleFirebaseProvider;
|
||||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -43,9 +42,6 @@ public class FirebaseConfig {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ServerConfig srvCfg;
|
private ServerConfig srvCfg;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private InvitationManager invMgr;
|
|
||||||
|
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private String credentials;
|
private String credentials;
|
||||||
private String database;
|
private String database;
|
||||||
@@ -87,9 +83,9 @@ public class FirebaseConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public AuthenticatorProvider getAuthProvider() {
|
public AuthenticatorProvider getAuthProvider() {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return new GoogleFirebaseAuthenticator(invMgr, false);
|
return new GoogleFirebaseAuthenticator(false);
|
||||||
} else {
|
} else {
|
||||||
return new GoogleFirebaseAuthenticator(invMgr, credentials, database, srvCfg.getName());
|
return new GoogleFirebaseAuthenticator(credentials, database, srvCfg.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import io.kamax.matrix.ThreePid;
|
|||||||
import io.kamax.mxisd.exception.BadRequestException;
|
import io.kamax.mxisd.exception.BadRequestException;
|
||||||
import io.kamax.mxisd.exception.MappingAlreadyExistsException;
|
import io.kamax.mxisd.exception.MappingAlreadyExistsException;
|
||||||
import io.kamax.mxisd.invitation.sender.IInviteSender;
|
import io.kamax.mxisd.invitation.sender.IInviteSender;
|
||||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
|
||||||
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;
|
||||||
import io.kamax.mxisd.signature.SignatureManager;
|
import io.kamax.mxisd.signature.SignatureManager;
|
||||||
@@ -99,7 +98,7 @@ public class InvitationManager {
|
|||||||
|
|
||||||
// TODO use caching mechanism
|
// TODO use caching mechanism
|
||||||
// TODO export in matrix-java-sdk
|
// TODO export in matrix-java-sdk
|
||||||
Optional<String> findHomeserverForDomain(String domain) {
|
String findHomeserverForDomain(String domain) {
|
||||||
log.debug("Performing SRV lookup for {}", domain);
|
log.debug("Performing SRV lookup for {}", domain);
|
||||||
String lookupDns = getSrvRecordName(domain);
|
String lookupDns = getSrvRecordName(domain);
|
||||||
log.info("Lookup name: {}", lookupDns);
|
log.info("Lookup name: {}", lookupDns);
|
||||||
@@ -110,7 +109,7 @@ public class InvitationManager {
|
|||||||
Arrays.sort(records, Comparator.comparingInt(SRVRecord::getPriority));
|
Arrays.sort(records, Comparator.comparingInt(SRVRecord::getPriority));
|
||||||
for (SRVRecord record : records) {
|
for (SRVRecord record : records) {
|
||||||
log.info("Found SRV record: {}", record.toString());
|
log.info("Found SRV record: {}", record.toString());
|
||||||
return Optional.of("https://" + record.getTarget().toString(true) + ":" + record.getPort());
|
return "https://" + record.getTarget().toString(true) + ":" + record.getPort();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info("No SRV record for {}", lookupDns);
|
log.info("No SRV record for {}", lookupDns);
|
||||||
@@ -120,7 +119,7 @@ public class InvitationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.info("Performing basic lookup using domain name {}", domain);
|
log.info("Performing basic lookup using domain name {}", domain);
|
||||||
return Optional.of("https://" + domain + ":8448");
|
return "https://" + domain + ":8448";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -143,13 +142,7 @@ public class InvitationManager {
|
|||||||
return invitations.get(pid);
|
return invitations.get(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleLookupRequest request = new SingleLookupRequest();
|
Optional<?> result = lookupMgr.find(invitation.getMedium(), invitation.getAddress(), true);
|
||||||
request.setType(invitation.getMedium());
|
|
||||||
request.setThreePid(invitation.getAddress());
|
|
||||||
request.setRecursive(true);
|
|
||||||
request.setRequester("Internal");
|
|
||||||
|
|
||||||
Optional<?> result = lookupMgr.findRecursive(request);
|
|
||||||
if (result.isPresent()) {
|
if (result.isPresent()) {
|
||||||
log.info("Mapping for {}:{} already exists, refusing to store invite", pid.getMedium(), pid.getAddress());
|
log.info("Mapping for {}:{} already exists, refusing to store invite", pid.getMedium(), pid.getAddress());
|
||||||
throw new MappingAlreadyExistsException();
|
throw new MappingAlreadyExistsException();
|
||||||
@@ -180,14 +173,11 @@ public class InvitationManager {
|
|||||||
log.info("{}:{} has an invite pending, publishing mapping", threePid.getMedium(), threePid.getValue());
|
log.info("{}:{} has an invite pending, publishing mapping", threePid.getMedium(), threePid.getValue());
|
||||||
String domain = reply.getInvite().getSender().getDomain();
|
String domain = reply.getInvite().getSender().getDomain();
|
||||||
log.info("Discovering HS for domain {}", domain);
|
log.info("Discovering HS for domain {}", domain);
|
||||||
Optional<String> hsUrlOpt = findHomeserverForDomain(domain);
|
String hsUrlOpt = findHomeserverForDomain(domain);
|
||||||
if (!hsUrlOpt.isPresent()) {
|
|
||||||
log.warn("No HS found for domain {} - ignoring publishing", domain);
|
|
||||||
} else {
|
|
||||||
// TODO this is needed as this will block if called during authentication cycle due to synapse implementation
|
|
||||||
|
|
||||||
|
// TODO this is needed as this will block if called during authentication cycle due to synapse implementation
|
||||||
new Thread(() -> { // FIXME need to make this retry-able and within a general background working pool
|
new Thread(() -> { // FIXME need to make this retry-able and within a general background working pool
|
||||||
HttpPost req = new HttpPost(hsUrlOpt.get() + "/_matrix/federation/v1/3pid/onbind");
|
HttpPost req = new HttpPost(hsUrlOpt + "/_matrix/federation/v1/3pid/onbind");
|
||||||
// Expected body: https://matrix.to/#/!HUeDbmFUsWAhxHHvFG:matrix.org/$150469846739DCLWc:matrix.trancendances.fr
|
// Expected body: https://matrix.to/#/!HUeDbmFUsWAhxHHvFG:matrix.org/$150469846739DCLWc:matrix.trancendances.fr
|
||||||
JSONObject obj = new JSONObject(); // TODO use Gson instead
|
JSONObject obj = new JSONObject(); // TODO use Gson instead
|
||||||
obj.put("mxid", threePid.getMxid());
|
obj.put("mxid", threePid.getMxid());
|
||||||
@@ -202,8 +192,6 @@ public class InvitationManager {
|
|||||||
objUp.put("room_id", reply.getInvite().getRoomId());
|
objUp.put("room_id", reply.getInvite().getRoomId());
|
||||||
objUp.put("signed", obj);
|
objUp.put("signed", obj);
|
||||||
|
|
||||||
String mapping = gson.toJson(objUp); // FIXME we shouldn't need to be doing this
|
|
||||||
|
|
||||||
JSONObject content = new JSONObject(); // TODO use Gson instead
|
JSONObject content = new JSONObject(); // TODO use Gson instead
|
||||||
JSONArray invites = new JSONArray();
|
JSONArray invites = new JSONArray();
|
||||||
invites.put(objUp);
|
invites.put(objUp);
|
||||||
@@ -233,7 +221,4 @@ public class InvitationManager {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
package io.kamax.mxisd.lookup;
|
package io.kamax.mxisd.lookup;
|
||||||
|
|
||||||
import groovy.json.JsonOutput;
|
import groovy.json.JsonOutput;
|
||||||
|
import io.kamax.mxisd.ThreePid;
|
||||||
|
|
||||||
public class ThreePidMapping {
|
public class ThreePidMapping {
|
||||||
|
|
||||||
@@ -32,6 +33,10 @@ public class ThreePidMapping {
|
|||||||
// stub
|
// stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ThreePidMapping(ThreePid threePid, String mxid) {
|
||||||
|
this(threePid.getMedium(), threePid.getAddress(), mxid);
|
||||||
|
}
|
||||||
|
|
||||||
public ThreePidMapping(String medium, String value, String mxid) {
|
public ThreePidMapping(String medium, String value, String mxid) {
|
||||||
setMedium(medium);
|
setMedium(medium);
|
||||||
setValue(value);
|
setValue(value);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class GoogleFirebaseProvider implements IThreePidProvider {
|
|||||||
this(true);
|
this(true);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
try {
|
try {
|
||||||
fbApp = FirebaseApp.initializeApp(getOpts(credsPath, db));
|
fbApp = FirebaseApp.initializeApp(getOpts(credsPath, db), "ThreePidProvider");
|
||||||
fbAuth = FirebaseAuth.getInstance(fbApp);
|
fbAuth = FirebaseAuth.getInstance(fbApp);
|
||||||
|
|
||||||
log.info("Google Firebase Authentication is ready");
|
log.info("Google Firebase Authentication is ready");
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ interface LookupStrategy {
|
|||||||
|
|
||||||
List<IThreePidProvider> getLocalProviders()
|
List<IThreePidProvider> getLocalProviders()
|
||||||
|
|
||||||
|
Optional<?> find(String medium, String address, boolean recursive)
|
||||||
|
|
||||||
Optional<?> find(SingleLookupRequest request)
|
Optional<?> find(SingleLookupRequest request)
|
||||||
|
|
||||||
Optional<?> findRecursive(SingleLookupRequest request)
|
Optional<?> findRecursive(SingleLookupRequest request)
|
||||||
|
|||||||
@@ -121,6 +121,16 @@ class RecursivePriorityLookupStrategy implements LookupStrategy, InitializingBea
|
|||||||
}).collect(Collectors.toList())
|
}).collect(Collectors.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Optional<?> find(String medium, String address, boolean recursive) {
|
||||||
|
SingleLookupRequest req = new SingleLookupRequest();
|
||||||
|
req.setType(medium)
|
||||||
|
req.setThreePid(address)
|
||||||
|
req.setRequester("Internal")
|
||||||
|
return find(req, recursive)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
Optional<?> find(SingleLookupRequest request, boolean forceRecursive) {
|
Optional<?> find(SingleLookupRequest request, boolean forceRecursive) {
|
||||||
for (IThreePidProvider provider : listUsableProviders(request, forceRecursive)) {
|
for (IThreePidProvider provider : listUsableProviders(request, forceRecursive)) {
|
||||||
Optional<?> lookupDataOpt = provider.find(request)
|
Optional<?> lookupDataOpt = provider.find(request)
|
||||||
|
|||||||
Reference in New Issue
Block a user