Refactor lookup providers

- Create lookup strategy object to handle several provider
- New root ID server provider
- Refactor code into appropriate classes
This commit is contained in:
Maxime Dor
2017-01-27 01:47:08 +01:00
parent 9f3ebb1ebf
commit 53d7114352
7 changed files with 170 additions and 42 deletions

View File

@@ -0,0 +1,7 @@
package io.kamax.mxisd.api
enum ThreePidType {
email
}

View File

@@ -21,14 +21,9 @@
package io.kamax.mxisd.controller.v1
import groovy.json.JsonOutput
import io.kamax.mxisd.config.LdapConfig
import io.kamax.mxisd.exception.BadRequestException
import io.kamax.mxisd.api.ThreePidType
import io.kamax.mxisd.lookup.LookupStrategy
import io.kamax.mxisd.signature.SignatureManager
import org.apache.directory.api.ldap.model.cursor.EntryCursor
import org.apache.directory.api.ldap.model.entry.Attribute
import org.apache.directory.api.ldap.model.message.SearchScope
import org.apache.directory.ldap.client.api.LdapConnection
import org.apache.directory.ldap.client.api.LdapNetworkConnection
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
@@ -40,50 +35,25 @@ import static org.springframework.web.bind.annotation.RequestMethod.GET
class MappingController {
@Autowired
private LdapConfig ldapCfg
private LookupStrategy strategy
@Autowired
private SignatureManager signMgr
@RequestMapping(value = "/_matrix/identity/api/v1/lookup", method = GET)
String lookup(@RequestParam String medium, @RequestParam String address) {
if (!"email".contentEquals(medium)) {
throw new BadRequestException("Invalid medium type")
ThreePidType type = ThreePidType.valueOf(medium)
Optional<?> lookupOpt = strategy.find(type, address)
if (!lookupOpt.isPresent()) {
return JsonOutput.toJson([])
}
LdapConnection conn = new LdapNetworkConnection(ldapCfg.getHost(), ldapCfg.getPort())
try {
conn.bind(ldapCfg.getBindDn(), ldapCfg.getBindPassword())
String searchQuery = ldapCfg.getQuery().replaceAll("%3pid", address)
EntryCursor cursor = conn.search(ldapCfg.getBaseDn(), searchQuery, SearchScope.SUBTREE, ldapCfg.getAttribute())
try {
if (!cursor.next()) {
return JsonOutput.toJson([])
}
Attribute attribute = cursor.get().get(ldapCfg.getAttribute())
if (attribute == null) {
return JsonOutput.toJson([])
}
def data = new LinkedHashMap([
address : address,
medium : medium,
mxid : attribute.get().toString(),
not_before: 0,
not_after : 9223372036854775807,
ts : 0
])
data['signatures'] = signMgr.signMessage(JsonOutput.toJson(data))
return JsonOutput.toJson(data)
} finally {
cursor.close()
}
} finally {
conn.close()
def lookup = lookupOpt.get()
if (lookup['signatures'] == null) {
lookup['signatures'] = signMgr.signMessage(JsonOutput.toJson(lookup))
}
return JsonOutput.toJson(lookup)
}
}

View File

@@ -0,0 +1,56 @@
package io.kamax.mxisd.lookup
import io.kamax.mxisd.api.ThreePidType
import io.kamax.mxisd.config.LdapConfig
import org.apache.directory.api.ldap.model.cursor.EntryCursor
import org.apache.directory.api.ldap.model.entry.Attribute
import org.apache.directory.api.ldap.model.message.SearchScope
import org.apache.directory.ldap.client.api.LdapConnection
import org.apache.directory.ldap.client.api.LdapNetworkConnection
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
class LdapProvider implements ThreePidProvider {
@Autowired
private LdapConfig ldapCfg
@Override
int getPriority() {
return 20
}
@Override
Optional<?> find(ThreePidType type, String threePid) {
LdapConnection conn = new LdapNetworkConnection(ldapCfg.getHost(), ldapCfg.getPort())
try {
conn.bind(ldapCfg.getBindDn(), ldapCfg.getBindPassword())
String searchQuery = ldapCfg.getQuery().replaceAll("%3pid", threePid)
EntryCursor cursor = conn.search(ldapCfg.getBaseDn(), searchQuery, SearchScope.SUBTREE, ldapCfg.getAttribute())
try {
if (cursor.next()) {
Attribute attribute = cursor.get().get(ldapCfg.getAttribute())
if (attribute != null) {
return Optional.of([
address : threePid,
medium : type,
mxid : attribute.get().toString(),
not_before: 0,
not_after : 9223372036854775807,
ts : 0
])
}
}
} finally {
cursor.close()
}
} finally {
conn.close()
}
return Optional.empty()
}
}

View File

@@ -0,0 +1,9 @@
package io.kamax.mxisd.lookup
import io.kamax.mxisd.api.ThreePidType
interface LookupStrategy {
Optional<?> find(ThreePidType type, String threePid)
}

View File

@@ -0,0 +1,38 @@
package io.kamax.mxisd.lookup
import io.kamax.mxisd.api.ThreePidType
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
class PriorityLookupStrategy implements LookupStrategy {
@Autowired
private List<ThreePidProvider> providers
@Override
Optional<?> find(ThreePidType type, String threePid) {
if (ThreePidType.email != type) {
throw new IllegalArgumentException("${type} is currently not supported")
}
providers.sort(new Comparator<ThreePidProvider>() {
@Override
int compare(ThreePidProvider o1, ThreePidProvider o2) {
return Integer.compare(o2.getPriority(), o1.getPriority())
}
})
for (ThreePidProvider provider : providers) {
Optional<?> lookupDataOpt = provider.find(type, threePid)
if (lookupDataOpt.isPresent()) {
return lookupDataOpt
}
}
return Optional.empty()
}
}

View File

@@ -0,0 +1,34 @@
package io.kamax.mxisd.lookup
import groovy.json.JsonSlurper
import io.kamax.mxisd.api.ThreePidType
import org.springframework.stereotype.Component
@Component
class RootProvider implements ThreePidProvider {
private List<String> roots = Arrays.asList("https://matrix.org", "https://vector.im")
private JsonSlurper json = new JsonSlurper()
@Override
int getPriority() {
return 0
}
@Override
Optional<?> find(ThreePidType type, String threePid) {
for (String root : roots) {
HttpURLConnection rootSrvConn = (HttpURLConnection) new URL(
"${root}/_matrix/identity/api/v1/lookup?medium=${type}&address=${threePid}"
).openConnection()
def output = json.parseText(rootSrvConn.getInputStream().getText())
if (output['address'] != null) {
return Optional.of(output)
}
}
return Optional.empty()
}
}

View File

@@ -0,0 +1,14 @@
package io.kamax.mxisd.lookup
import io.kamax.mxisd.api.ThreePidType
interface ThreePidProvider {
/**
* Higher has more priority
*/
int getPriority() // Should not be here but let's KISS for now
Optional<?> find(ThreePidType type, String threePid)
}