Skeleton to support LDAP Auth
This commit is contained in:
@@ -97,41 +97,83 @@ lookup:
|
|||||||
|
|
||||||
|
|
||||||
ldap:
|
ldap:
|
||||||
|
|
||||||
|
# Global enable/disable switch
|
||||||
enabled: true
|
enabled: true
|
||||||
tls: false
|
|
||||||
host: 'localhost'
|
|
||||||
port: 389
|
|
||||||
bindDn: 'CN=Matrix Identity Server,CN=Users,DC=example,DC=org'
|
|
||||||
bindPassword: 'password'
|
|
||||||
baseDn: 'CN=Users,DC=example,DC=org'
|
|
||||||
|
|
||||||
# How should we resolve the Matrix ID in case of a match using the attribute.
|
# Connection configuration to the LDAP server
|
||||||
|
connection:
|
||||||
|
|
||||||
|
# If the connection should be secure
|
||||||
|
tls: false
|
||||||
|
|
||||||
|
# Host to connect to
|
||||||
|
host: 'localhost'
|
||||||
|
|
||||||
|
# Port to connect to
|
||||||
|
port: 389
|
||||||
|
|
||||||
|
# Bind DN to use when performing lookups
|
||||||
|
bindDn: 'CN=Matrix Identity Server,CN=Users,DC=example,DC=org'
|
||||||
|
|
||||||
|
# Bind password to use
|
||||||
|
bindPassword: 'password'
|
||||||
|
|
||||||
|
# Base DN used in all queries
|
||||||
|
baseDn: 'CN=Users,DC=example,DC=org'
|
||||||
|
|
||||||
|
# How to map Matrix attributes with LDAP attributes when performing lookup/auth
|
||||||
|
attributes:
|
||||||
|
|
||||||
|
# The username/login that will be looked up or used to build Matrix IDs
|
||||||
|
uid:
|
||||||
|
|
||||||
|
# How should we resolve the Matrix ID in case of a match using the attribute.
|
||||||
|
#
|
||||||
|
# The following type are supported:
|
||||||
|
# - uid : the attribute only contains the UID part of the Matrix ID. e.g. 'john.doe' in @john.doe:example.org
|
||||||
|
# - mxid : the attribute contains the full Matrix ID - e.g. '@john.doe:example.org'
|
||||||
|
type: 'uid'
|
||||||
|
|
||||||
|
# The attribute containing the binding itself. This value will be used differently depending on the type.
|
||||||
|
#
|
||||||
|
# /!\ This should match the synapse LDAP Authenticator 'uid' configuration /!\
|
||||||
|
#
|
||||||
|
# Typical values:
|
||||||
|
# - For type 'uid': 'userPrincipalName' or 'uid' or 'saMAccountName'
|
||||||
|
# - For type 'mxid', regardless of the directory type, we recommend using 'pager' as it is a standard attribute and
|
||||||
|
# is typically not used.
|
||||||
|
value: 'userPrincipalName'
|
||||||
|
|
||||||
|
# The display name of the user
|
||||||
|
name: 'displayName'
|
||||||
|
|
||||||
|
# Configuration section relating the authentication of users performed via LDAP.
|
||||||
#
|
#
|
||||||
# The following type are supported:
|
# This can be done using the REST Auth module for synapse and pointing it to the identity server.
|
||||||
# - uid : the attribute only contains the UID part of the Matrix ID. e.g. 'john.doe' in @john.doe:example.org
|
# See https://github.com/maxidor/matrix-synapse-rest-auth
|
||||||
# - mxid : the attribute contains the full Matrix ID - e.g. '@john.doe:example.org'
|
auth:
|
||||||
type: 'uid'
|
|
||||||
|
|
||||||
# The attribute containing the binding itself. This value will be used differently depending on the type.
|
# What to filter potential users by, typically by using a dedicated group.
|
||||||
#
|
# If this value is not set, login check will be performed for all entities within the LDAP
|
||||||
# /!\ This should match the synapse LDAP Authenticator 'uid' configuration /!\
|
|
||||||
#
|
|
||||||
# Typical values:
|
|
||||||
# - For type 'uid': 'userPrincipalName' or 'uid' or 'saMAccountName'
|
|
||||||
# - For type 'mxid', regardless of the directory type, we recommend using 'pager' as it is a standard attribute and
|
|
||||||
# is typically not used.
|
|
||||||
attribute: 'userPrincipalName'
|
|
||||||
|
|
||||||
# Configure each 3PID type with a dedicated query.
|
|
||||||
mappings:
|
|
||||||
email: "(|(mailPrimaryAddress=%3pid)(mail=%3pid)(otherMailbox=%3pid))"
|
|
||||||
|
|
||||||
# Phone numbers query.
|
|
||||||
#
|
#
|
||||||
# Phone numbers use the MSISDN format: https://en.wikipedia.org/wiki/MSISDN
|
# Example: (memberOf=CN=Matrix Users,CN=Users,DC=example,DC=org)
|
||||||
# This format does not include international prefix (+ or 00) and therefore has to be put in the query.
|
filter: ''
|
||||||
# Adapt this to your needs for each attribute.
|
|
||||||
msisdn: "(|(telephoneNumber=+%3pid)(mobile=+%3pid)(homePhone=+%3pid)(otherTelephone=+%3pid)(otherMobile=+%3pid)(otherHomePhone=+%3pid))"
|
# Configuration section relating to identity lookups
|
||||||
|
identity:
|
||||||
|
|
||||||
|
# Configure each 3PID type with a dedicated query.
|
||||||
|
medium:
|
||||||
|
# E-mail query
|
||||||
|
email: "(|(mailPrimaryAddress=%3pid)(mail=%3pid)(otherMailbox=%3pid))"
|
||||||
|
|
||||||
|
# Phone numbers query
|
||||||
|
#
|
||||||
|
# Phone numbers use the MSISDN format: https://en.wikipedia.org/wiki/MSISDN
|
||||||
|
# This format does not include international prefix (+ or 00) and therefore has to be put in the query.
|
||||||
|
# Adapt this to your needs for each attribute.
|
||||||
|
msisdn: "(|(telephoneNumber=+%3pid)(mobile=+%3pid)(homePhone=+%3pid)(otherTelephone=+%3pid)(otherMobile=+%3pid)(otherHomePhone=+%3pid))"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,156 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.config
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.beans.factory.InitializingBean
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
|
||||||
import org.springframework.context.annotation.Configuration
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConfigurationProperties(prefix = "ldap")
|
|
||||||
class LdapConfig implements InitializingBean {
|
|
||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger(LdapConfig.class)
|
|
||||||
|
|
||||||
private boolean enabled
|
|
||||||
private boolean tls
|
|
||||||
private String host
|
|
||||||
private int port
|
|
||||||
private String baseDn
|
|
||||||
private String type
|
|
||||||
private String attribute
|
|
||||||
private String bindDn
|
|
||||||
private String bindPassword
|
|
||||||
private Map<String, String> mappings
|
|
||||||
|
|
||||||
boolean getEnabled() {
|
|
||||||
return enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean getTls() {
|
|
||||||
return tls
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTls(boolean tls) {
|
|
||||||
this.tls = tls
|
|
||||||
}
|
|
||||||
|
|
||||||
String getHost() {
|
|
||||||
return host
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHost(String host) {
|
|
||||||
this.host = host
|
|
||||||
}
|
|
||||||
|
|
||||||
int getPort() {
|
|
||||||
return port
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPort(int port) {
|
|
||||||
this.port = port
|
|
||||||
}
|
|
||||||
|
|
||||||
String getBaseDn() {
|
|
||||||
return baseDn
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBaseDn(String baseDn) {
|
|
||||||
this.baseDn = baseDn
|
|
||||||
}
|
|
||||||
|
|
||||||
String getType() {
|
|
||||||
return type
|
|
||||||
}
|
|
||||||
|
|
||||||
void setType(String type) {
|
|
||||||
this.type = type
|
|
||||||
}
|
|
||||||
|
|
||||||
String getAttribute() {
|
|
||||||
return attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAttribute(String attribute) {
|
|
||||||
this.attribute = attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
String getBindDn() {
|
|
||||||
return bindDn
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBindDn(String bindDn) {
|
|
||||||
this.bindDn = bindDn
|
|
||||||
}
|
|
||||||
|
|
||||||
String getBindPassword() {
|
|
||||||
return bindPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBindPassword(String bindPassword) {
|
|
||||||
this.bindPassword = bindPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> getMappings() {
|
|
||||||
return mappings
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMappings(Map<String, String> mappings) {
|
|
||||||
this.mappings = mappings
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<String> getMapping(String type) {
|
|
||||||
if (mappings == null) {
|
|
||||||
return Optional.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.ofNullable(mappings.get(type))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void afterPropertiesSet() throws Exception {
|
|
||||||
log.info("LDAP enabled: {}", getEnabled())
|
|
||||||
|
|
||||||
if (!getEnabled()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Matrix ID type: {}", getType())
|
|
||||||
log.info("LDAP Host: {}", getHost())
|
|
||||||
log.info("LDAP Bind DN: {}", getBindDn())
|
|
||||||
log.info("LDAP Attribute: {}", getAttribute())
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(getHost())) {
|
|
||||||
throw new IllegalStateException("LDAP Host must be configured!")
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(getAttribute())) {
|
|
||||||
throw new IllegalStateException("LDAP attribute must be configured!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.kamax.mxisd.config.ldap;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap.attribute")
|
||||||
|
public class LdapAttributeConfig {
|
||||||
|
|
||||||
|
private LdapAttributeUidConfig uid;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public LdapAttributeUidConfig getUid() {
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUid(LdapAttributeUidConfig uid) {
|
||||||
|
this.uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.kamax.mxisd.config.ldap;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap.attribute.uid")
|
||||||
|
public class LdapAttributeUidConfig {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package io.kamax.mxisd.config.ldap;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap.auth")
|
||||||
|
public class LdapAuthConfig {
|
||||||
|
|
||||||
|
private String filter;
|
||||||
|
|
||||||
|
public String getFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilter(String filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
125
src/main/groovy/io/kamax/mxisd/config/ldap/LdapConfig.groovy
Normal file
125
src/main/groovy/io/kamax/mxisd/config/ldap/LdapConfig.groovy
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.ldap
|
||||||
|
|
||||||
|
import groovy.json.JsonOutput
|
||||||
|
import org.apache.commons.lang.StringUtils
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap")
|
||||||
|
class LdapConfig {
|
||||||
|
|
||||||
|
private Logger log = LoggerFactory.getLogger(LdapConfig.class)
|
||||||
|
|
||||||
|
private boolean enabled
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LdapConnectionConfig conn
|
||||||
|
private LdapAttributeConfig attribute
|
||||||
|
private LdapAuthConfig auth
|
||||||
|
private LdapIdentityConfig identity
|
||||||
|
|
||||||
|
boolean isEnabled() {
|
||||||
|
return enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapConnectionConfig getConn() {
|
||||||
|
return conn
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConn(LdapConnectionConfig conn) {
|
||||||
|
this.conn = conn
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapAttributeConfig getAttribute() {
|
||||||
|
return attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAttribute(LdapAttributeConfig attribute) {
|
||||||
|
this.attribute = attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapAuthConfig getAuth() {
|
||||||
|
return auth
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAuth(LdapAuthConfig auth) {
|
||||||
|
this.auth = auth
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapIdentityConfig getIdentity() {
|
||||||
|
return identity
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIdentity(LdapIdentityConfig identity) {
|
||||||
|
this.identity = identity
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
void afterPropertiesSet() {
|
||||||
|
log.info("--- LDAP Config ---")
|
||||||
|
log.info("Enabled: {}", isEnabled())
|
||||||
|
|
||||||
|
if (!isEnabled()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(conn.getHost())) {
|
||||||
|
throw new IllegalStateException("LDAP Host must be configured!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 > conn.getPort() || 65535 < conn.getPort()) {
|
||||||
|
throw new IllegalStateException("LDAP port is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(attribute.getUid().getType())) {
|
||||||
|
throw new IllegalStateException("Attribute UID Type cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(attribute.getUid().getValue())) {
|
||||||
|
throw new IllegalStateException("Attribute UID value cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.info("Conn: {}", JsonOutput.toJson(conn))
|
||||||
|
log.info("Host: {}", conn.getHost())
|
||||||
|
log.info("Port: {}", conn.getPort())
|
||||||
|
log.info("Bind DN: {}", conn.getBindDn())
|
||||||
|
log.info("Base DN: {}", conn.getBaseDn())
|
||||||
|
|
||||||
|
log.info("Attribute: {}", JsonOutput.toJson(attribute))
|
||||||
|
log.info("Auth: {}", JsonOutput.toJson(auth))
|
||||||
|
log.info("Identity: {}", JsonOutput.toJson(identity))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package io.kamax.mxisd.config.ldap;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap.connection")
|
||||||
|
public class LdapConnectionConfig {
|
||||||
|
|
||||||
|
private boolean tls;
|
||||||
|
private String host;
|
||||||
|
private int port;
|
||||||
|
private String bindDn;
|
||||||
|
private String bindPassword;
|
||||||
|
private String baseDn;
|
||||||
|
|
||||||
|
public boolean isTls() {
|
||||||
|
return tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTls(boolean tls) {
|
||||||
|
this.tls = tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBindDn() {
|
||||||
|
return bindDn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBindDn(String bindDn) {
|
||||||
|
this.bindDn = bindDn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBindPassword() {
|
||||||
|
return bindPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBindPassword(String bindPassword) {
|
||||||
|
this.bindPassword = bindPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBaseDn() {
|
||||||
|
return baseDn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaseDn(String baseDn) {
|
||||||
|
this.baseDn = baseDn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package io.kamax.mxisd.config.ldap;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "ldap.identity")
|
||||||
|
public class LdapIdentityConfig {
|
||||||
|
|
||||||
|
private Map<String, String> medium = new HashMap<>();
|
||||||
|
|
||||||
|
public Map<String, String> getMedium() {
|
||||||
|
return medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getQuery(String key) {
|
||||||
|
return Optional.ofNullable(medium.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedium(Map<String, String> medium) {
|
||||||
|
this.medium = medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,8 +20,10 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd.lookup.provider
|
package io.kamax.mxisd.lookup.provider
|
||||||
|
|
||||||
import io.kamax.mxisd.config.LdapConfig
|
import io.kamax.mxisd.auth.UserAuthResult
|
||||||
|
import io.kamax.mxisd.auth.provider.AuthenticatorProvider
|
||||||
import io.kamax.mxisd.config.ServerConfig
|
import io.kamax.mxisd.config.ServerConfig
|
||||||
|
import io.kamax.mxisd.config.ldap.LdapConfig
|
||||||
import io.kamax.mxisd.lookup.SingleLookupRequest
|
import io.kamax.mxisd.lookup.SingleLookupRequest
|
||||||
import io.kamax.mxisd.lookup.ThreePidMapping
|
import io.kamax.mxisd.lookup.ThreePidMapping
|
||||||
import org.apache.commons.lang.StringUtils
|
import org.apache.commons.lang.StringUtils
|
||||||
@@ -38,7 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired
|
|||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class LdapProvider implements IThreePidProvider {
|
class LdapProvider implements IThreePidProvider, AuthenticatorProvider {
|
||||||
|
|
||||||
public static final String UID = "uid"
|
public static final String UID = "uid"
|
||||||
public static final String MATRIX_ID = "mxid"
|
public static final String MATRIX_ID = "mxid"
|
||||||
@@ -53,7 +55,28 @@ class LdapProvider implements IThreePidProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isEnabled() {
|
boolean isEnabled() {
|
||||||
return ldapCfg.getEnabled()
|
return ldapCfg.isEnabled()
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapConnection getConn() {
|
||||||
|
return new LdapNetworkConnection(ldapCfg.getConn().getHost(), ldapCfg.getConn().getPort(), ldapCfg.getConn().isTls())
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bind(LdapConnection conn) {
|
||||||
|
conn.bind(ldapCfg.getConn().getBindDn(), ldapCfg.getConn().getBindPassword())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
UserAuthResult authenticate(String id, String password) {
|
||||||
|
LdapConnection conn = getConn()
|
||||||
|
try {
|
||||||
|
bind(conn)
|
||||||
|
|
||||||
|
// TODO finish this
|
||||||
|
return new UserAuthResult().failure()
|
||||||
|
} finally {
|
||||||
|
conn.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,20 +90,22 @@ class LdapProvider implements IThreePidProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<String> lookup(LdapConnection conn, String medium, String value) {
|
Optional<String> lookup(LdapConnection conn, String medium, String value) {
|
||||||
Optional<String> queryOpt = ldapCfg.getMapping(medium)
|
String uidAttribute = ldapCfg.getAttribute().getUid().getValue()
|
||||||
|
|
||||||
|
Optional<String> queryOpt = ldapCfg.getIdentity().getQuery(medium)
|
||||||
if (!queryOpt.isPresent()) {
|
if (!queryOpt.isPresent()) {
|
||||||
log.warn("{} is not a configured 3PID type for LDAP lookup", medium)
|
log.warn("{} is not a configured 3PID type for LDAP lookup", medium)
|
||||||
return Optional.empty()
|
return Optional.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
String searchQuery = queryOpt.get().replaceAll("%3pid", value)
|
String searchQuery = queryOpt.get().replaceAll("%3pid", value)
|
||||||
EntryCursor cursor = conn.search(ldapCfg.getBaseDn(), searchQuery, SearchScope.SUBTREE, ldapCfg.getAttribute())
|
EntryCursor cursor = conn.search(ldapCfg.getConn().getBaseDn(), searchQuery, SearchScope.SUBTREE, uidAttribute)
|
||||||
try {
|
try {
|
||||||
while (cursor.next()) {
|
while (cursor.next()) {
|
||||||
Entry entry = cursor.get()
|
Entry entry = cursor.get()
|
||||||
log.info("Found possible match, DN: {}", entry.getDn().getName())
|
log.info("Found possible match, DN: {}", entry.getDn().getName())
|
||||||
|
|
||||||
Attribute attribute = entry.get(ldapCfg.getAttribute())
|
Attribute attribute = entry.get(uidAttribute)
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
log.info("DN {}: no attribute {}, skpping", entry.getDn(), ldapCfg.getAttribute())
|
log.info("DN {}: no attribute {}, skpping", entry.getDn(), ldapCfg.getAttribute())
|
||||||
continue
|
continue
|
||||||
@@ -94,12 +119,13 @@ class LdapProvider implements IThreePidProvider {
|
|||||||
|
|
||||||
StringBuilder matrixId = new StringBuilder()
|
StringBuilder matrixId = new StringBuilder()
|
||||||
// TODO Should we turn this block into a map of functions?
|
// TODO Should we turn this block into a map of functions?
|
||||||
if (StringUtils.equals(UID, ldapCfg.getType())) {
|
String uidType = ldapCfg.getAttribute().getUid().getType()
|
||||||
|
if (StringUtils.equals(UID, uidType)) {
|
||||||
matrixId.append("@").append(data).append(":").append(srvCfg.getName())
|
matrixId.append("@").append(data).append(":").append(srvCfg.getName())
|
||||||
} else if (StringUtils.equals(MATRIX_ID, ldapCfg.getType())) {
|
} else if (StringUtils.equals(MATRIX_ID, uidType)) {
|
||||||
matrixId.append(data)
|
matrixId.append(data)
|
||||||
} else {
|
} else {
|
||||||
log.warn("Bind was found but type {} is not supported", ldapCfg.getType())
|
log.warn("Bind was found but type {} is not supported", uidType)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +145,9 @@ class LdapProvider implements IThreePidProvider {
|
|||||||
Optional<?> find(SingleLookupRequest request) {
|
Optional<?> find(SingleLookupRequest request) {
|
||||||
log.info("Performing LDAP lookup ${request.getThreePid()} of type ${request.getType()}")
|
log.info("Performing LDAP lookup ${request.getThreePid()} of type ${request.getType()}")
|
||||||
|
|
||||||
LdapConnection conn = new LdapNetworkConnection(ldapCfg.getHost(), ldapCfg.getPort(), ldapCfg.getTls())
|
LdapConnection conn = getConn()
|
||||||
try {
|
try {
|
||||||
conn.bind(ldapCfg.getBindDn(), ldapCfg.getBindPassword())
|
bind(conn)
|
||||||
|
|
||||||
Optional<String> mxid = lookup(conn, request.getType(), request.getThreePid())
|
Optional<String> mxid = lookup(conn, request.getType(), request.getThreePid())
|
||||||
if (mxid.isPresent()) {
|
if (mxid.isPresent()) {
|
||||||
@@ -147,9 +173,9 @@ class LdapProvider implements IThreePidProvider {
|
|||||||
log.info("Looking up {} mappings", mappings.size())
|
log.info("Looking up {} mappings", mappings.size())
|
||||||
List<ThreePidMapping> mappingsFound = new ArrayList<>()
|
List<ThreePidMapping> mappingsFound = new ArrayList<>()
|
||||||
|
|
||||||
LdapConnection conn = new LdapNetworkConnection(ldapCfg.getHost(), ldapCfg.getPort())
|
LdapConnection conn = getConn()
|
||||||
try {
|
try {
|
||||||
conn.bind(ldapCfg.getBindDn(), ldapCfg.getBindPassword())
|
bind(conn)
|
||||||
|
|
||||||
for (ThreePidMapping mapping : mappings) {
|
for (ThreePidMapping mapping : mappings) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user