diff --git a/ma1sd.example.yaml b/ma1sd.example.yaml index f85cc70..8248e52 100644 --- a/ma1sd.example.yaml +++ b/ma1sd.example.yaml @@ -165,6 +165,8 @@ threepid: # ldap: # enabled: true # lookup: true # hash lookup +# activeDirectory: false +# defaultDomain: '' # connection: # host: 'ldap.domain.tld' # port: 389 diff --git a/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java b/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java index ba04a0d..8a6a018 100644 --- a/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/ldap/LdapBackend.java @@ -20,6 +20,7 @@ package io.kamax.mxisd.backend.ldap; +import io.kamax.matrix.MatrixID; import io.kamax.matrix._MatrixID; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ldap.LdapConfig; @@ -116,10 +117,16 @@ public abstract class LdapBackend { public String buildMatrixIdFromUid(String uid) { String uidType = getCfg().getAttribute().getUid().getType(); + String localpart = uid; + if (StringUtils.equals(UID, uidType)) { - return "@" + uid + ":" + mxCfg.getDomain(); + if(getCfg().isActiveDirectory()) { + localpart = new UPN(uid).getMXID(); + } + + return "@" + localpart + ":" + mxCfg.getDomain(); } else if (StringUtils.equals(MATRIX_ID, uidType)) { - return uid; + return localpart; } else { throw new IllegalArgumentException("Bind type " + uidType + " is not supported"); } @@ -128,6 +135,10 @@ public abstract class LdapBackend { public String buildUidFromMatrixId(_MatrixID mxId) { String uidType = getCfg().getAttribute().getUid().getType(); if (StringUtils.equals(UID, uidType)) { + if(getCfg().isActiveDirectory()) { + return new UPN(mxId).getUPN(); + } + return mxId.getLocalPart(); } else if (StringUtils.equals(MATRIX_ID, uidType)) { return mxId.getId(); @@ -169,4 +180,58 @@ public abstract class LdapBackend { return values; } + private class UPN { + private String login; + private String domain; + + public UPN(String userPrincipalName) { + String[] uidParts = userPrincipalName.split("@"); + + if (uidParts.length != 2) { + throw new IllegalArgumentException(String.format("Wrong userPrincipalName provided: %s", userPrincipalName)); + } + + this.login = uidParts[0]; + this.domain = uidParts[1]; + } + + public UPN(_MatrixID mxid) { + String[] idParts = mxid.getLocalPart().split("/"); + + if (idParts.length != 2) { + if(idParts.length == 1 && !StringUtils.isEmpty(getCfg().getDefaultDomain())) { + throw new IllegalArgumentException(String.format( + "Local part of mxid %s does not contains domain separator and default domain is not configured", + mxid.getLocalPart() + )); + } + + this.domain = getCfg().getDefaultDomain(); + } else { + this.domain = idParts[1]; + } + + this.login = idParts[0]; + } + + public String getLogin() { + return login; + } + + public String getDomain() { + return domain; + } + + public String getMXID() { + if(StringUtils.equalsIgnoreCase(getCfg().getDefaultDomain(), this.domain)) { + return this.login; + } + + return new StringBuilder(this.login).append("/").append(this.domain).toString(); + } + + public String getUPN() { + return new StringBuilder(this.login).append("@").append(this.domain).toString(); + } + } } diff --git a/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java b/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java index 4519062..1c1a69d 100644 --- a/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ldap/LdapConfig.java @@ -291,6 +291,9 @@ public abstract class LdapConfig { private boolean enabled; private String filter; + private boolean activeDirectory; + private String defaultDomain; + private Connection connection = new Connection(); private Attribute attribute = new Attribute(); private Auth auth = new Auth(); @@ -316,6 +319,22 @@ public abstract class LdapConfig { this.filter = filter; } + public boolean isActiveDirectory() { + return activeDirectory; + } + + public void setActiveDirectory(boolean activeDirectory) { + this.activeDirectory = activeDirectory; + } + + public String getDefaultDomain() { + return defaultDomain; + } + + public void setDefaultDomain(String defaultDomain) { + this.defaultDomain = defaultDomain; + } + public Connection getConnection() { return connection; } @@ -407,6 +426,15 @@ public abstract class LdapConfig { throw new ConfigurationException("ldap.identity.token"); } + if(isActiveDirectory()) { + if(!StringUtils.equals(LdapBackend.UID, uidType)) { + throw new IllegalArgumentException(String.format( + "Attribute UID type should be set to %s in Active Directory mode", + LdapBackend.UID + )); + } + } + // Build queries attribute.getThreepid().forEach((k, v) -> { if (StringUtils.isBlank(identity.getMedium().get(k))) {