Compare commits

..

11 Commits

Author SHA1 Message Date
Maxime Dor
e2b3920840 Directory: document HS exclusion config option 2017-11-22 19:40:16 +01:00
Maxime Dor
aaa742f6d2 LDAP: Properly handle multi-value attributes 2017-11-17 16:51:16 +01:00
Maxime Dor
959feb686c Improve auth doc 2017-11-16 22:35:16 +01:00
Maxime Dor
d9c5c5056a Improve getting started wording 2017-11-15 21:01:33 +01:00
Maxime Dor
83fafdcfeb Add config option to disable HS lookup for directory searches 2017-11-06 11:16:22 +01:00
Maxime Dor
e916ecd08b Properly handle Synapse as an Identity provider 2017-10-30 17:43:22 +01:00
Maxime Dor
1461d8ef6c Add fixme to prevent using mxisd DB as synapse identity store 2017-10-30 16:42:00 +01:00
Maxime Dor
19c1214e4a Fix release version extraction from git tags 2017-10-25 00:40:43 +02:00
Maxime Dor
b976f69c39 Fix systemd log format 2017-10-17 15:59:16 +02:00
Maxime Dor
3675da4a0f Specify that LDAP now supports profile auto-fill 2017-10-11 21:08:10 +02:00
Max Dor
077955d538 Set theme jekyll-theme-cayman 2017-10-09 19:18:37 +02:00
21 changed files with 311 additions and 110 deletions

View File

@@ -47,7 +47,7 @@ String gitVersion() {
def versionPattern = Pattern.compile("v(\\d+\\.)?(\\d+\\.)?(\\d+)(-.*)?") def versionPattern = Pattern.compile("v(\\d+\\.)?(\\d+\\.)?(\\d+)(-.*)?")
ByteArrayOutputStream out = new ByteArrayOutputStream() ByteArrayOutputStream out = new ByteArrayOutputStream()
exec { exec {
commandLine = ['git', 'describe', '--always', '--dirty'] commandLine = ['git', 'describe', '--tags', '--always', '--dirty']
standardOutput = out standardOutput = out
} }
def v = out.toString().replace(System.lineSeparator(), '') def v = out.toString().replace(System.lineSeparator(), '')

1
docs/_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-cayman

View File

@@ -43,7 +43,8 @@ ldap.attribute.name: 'cn'
``` ```
You can also change the attribute lists for 3PID, like email or phone numbers. You can also change the attribute lists for 3PID, like email or phone numbers.
The following example would overwrite the [default list of attributes](../../src/main/resources/application.yaml#L67) for emails and phone number: The following example would overwrite the [default list of attributes](../../src/main/resources/application.yaml#L67)
for emails and phone number:
``` ```
ldap.attribute.threepid.email: ldap.attribute.threepid.email:
- 'mail' - 'mail'
@@ -65,7 +66,8 @@ of the Configuration below.
No further configuration is needed to enable authentication with LDAP once globally enabled and configured. No further configuration is needed to enable authentication with LDAP once globally enabled and configured.
You have the possiblity to use a different query filter if you wish, see Configuration below. You have the possiblity to use a different query filter if you wish, see Configuration below.
Profile auto-fill is not yet supported but is a top priority. Profile auto-fill is enabled by default. It will use the `name` and `threepid` configuration options to get a lit of
attributes to be used to build the user profile to pass on to synapse during authentication.
## Directory ## Directory
No further configuration is needed to enable directory with LDAP once globally enabled and configured. No further configuration is needed to enable directory with LDAP once globally enabled and configured.

View File

@@ -27,22 +27,27 @@ It allows to use Identity stores configured in mxisd to authenticate users on yo
Performed on [synapse with REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth/blob/master/README.md) Performed on [synapse with REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth/blob/master/README.md)
## Getting started ## Getting started
Authentication is possible by linking synapse and mxisd together using the REST auth module
(also known as password provider).
### Synapse ### Synapse
You will need: - Install the [REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth).
- Edit your synapse configuration:
- As described by the auth module documentation
- Set `endpoint` to `http://mxisdAddress:8090` - Replace `mxisdAddress` by an IP/host name that provides a direct
connection to mxisd.
This **MUST NOT** be a public address, and SHOULD NOT go through a reverse proxy.
- Restart synapse
### mxisd
- Configure and enable at least one [Identity store](../backends/) - Configure and enable at least one [Identity store](../backends/)
- Install the [REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth) - Restart mxisd
Once installed, edit your synapse configuration as described for the auth module: ### Validate
- Set `endpoint` to `http://mxisdAddress:8090` - Replace `mxisdAddress` to an internal IP/Hostname. Login on the Homeserver using credentials present in your backend.
- If you want to avoid [known issues](https://github.com/matrix-org/matrix-doc/issues/586) with lower/upper case
usernames, set `enforceLowercase` in the REST config to `true`.
**IMPORTANT**: if this is a new installation, it is highly recommended to enforce lowercase, as it is not possible to ## Next steps
workaround the bug at a later date and will cause issues with invites, searches, authentication. ### Profile auto-fill
Restart synapse and login on the Homeserver using credentials present in your backend.
## Profile auto-fill
Auto-filling user profile depends on two conditions: Auto-filling user profile depends on two conditions:
- The REST auth module is configured for it, which is the case by default - The REST auth module is configured for it, which is the case by default
- Your Identity store is configured to provide profile data. See your Identity store [documentation](../backends/) on - Your Identity store is configured to provide profile data. See your Identity store [documentation](../backends/) on

View File

@@ -9,6 +9,7 @@
- [LDAP](#ldap) - [LDAP](#ldap)
- [SQL](#sql) - [SQL](#sql)
- [REST](#rest) - [REST](#rest)
- [Next steps](#next-steps)
## Description ## Description
This feature allows you to search for existing and/or potential users that are already present in your Identity backend This feature allows you to search for existing and/or potential users that are already present in your Identity backend
@@ -165,3 +166,11 @@ For each query, `type` can be used to tell mxisd how to process the ID column:
#### REST #### REST
See the [dedicated document](../backends/rest.md) See the [dedicated document](../backends/rest.md)
## Next steps
### Homeserver results
You can configure if the Homeserver should be queried at all when doing a directory search.
To disable Homeserver results, set the following in mxisd config file:
```
directory.exclude.homeserever: true
```

View File

@@ -54,7 +54,8 @@ Complete configuration guide is available [here](configure.md).
For an overview of a typical mxisd infrastructure, see the [dedicated document](architecture.md) For an overview of a typical mxisd infrastructure, see the [dedicated document](architecture.md)
### Reverse proxy ### Reverse proxy
#### Apache2 #### Apache2
In the VirtualHost handling the domain with SSL, add the following line and replace `0.0.0.0` by the right address/host. In the VirtualHost handling the domain with SSL, add the following line and replace `0.0.0.0` by the internal IP/hostname
pointing to mxisd.
**This line MUST be present before the one for the homeserver!** **This line MUST be present before the one for the homeserver!**
``` ```
ProxyPass /_matrix/identity/ http://0.0.0.0:8090/_matrix/identity/ ProxyPass /_matrix/identity/ http://0.0.0.0:8090/_matrix/identity/
@@ -82,7 +83,7 @@ trusted_third_party_id_servers:
- vector.im - vector.im
- example.org - example.org
``` ```
It is recommended to remove `matrix.org` and `vector.im` so only your own Identity server is allowed by synapse. It is recommended to remove `matrix.org` and `vector.im` so only your own Identity server is authoritative for your HS.
## Validate ## Validate
Log in using your Matrix client and set `https://example.org` as your Identity server URL, replacing `example.org` by Log in using your Matrix client and set `https://example.org` as your Identity server URL, replacing `example.org` by

View File

@@ -46,6 +46,7 @@ import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -133,14 +134,20 @@ public class LdapAuthProvider extends LdapGenericBackend implements Authenticato
// TODO should we canonicalize the MXID? // TODO should we canonicalize the MXID?
BackendAuthResult result = BackendAuthResult.success(mxid.getId(), UserIdType.MatrixID, name); BackendAuthResult result = BackendAuthResult.success(mxid.getId(), UserIdType.MatrixID, name);
log.info("Processing 3PIDs for profile"); log.info("Processing 3PIDs for profile");
getAt().getThreepid().forEach((k, v) -> v.forEach(attId -> { getAt().getThreepid().forEach((k, v) -> {
getAttribute(entry, attId).ifPresent(tpidValue -> { log.info("Processing 3PID type {}", k);
v.forEach(attId -> {
List<String> values = getAttributes(entry, attId);
log.info("\tAttribute {} has {} value(s)", attId, values.size());
getAttributes(entry, attId).forEach(tpidValue -> {
if (ThreePidMedium.PhoneNumber.is(k)) { if (ThreePidMedium.PhoneNumber.is(k)) {
tpidValue = getMsisdn(tpidValue).orElse(tpidValue); tpidValue = getMsisdn(tpidValue).orElse(tpidValue);
} }
result.withThreePid(new ThreePid(k, tpidValue)); result.withThreePid(new ThreePid(k, tpidValue));
}); });
})); });
});
log.info("Found {} 3PIDs", result.getProfile().getThreePids().size()); log.info("Found {} 3PIDs", result.getProfile().getThreePids().size());
return result; return result;
} }

View File

@@ -25,6 +25,7 @@ import io.kamax.mxisd.config.ldap.LdapAttributeConfig;
import io.kamax.mxisd.config.ldap.LdapConfig; import io.kamax.mxisd.config.ldap.LdapConfig;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.directory.api.ldap.model.entry.Attribute; import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.AttributeUtils;
import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException; import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.ldap.client.api.LdapConnection; import org.apache.directory.ldap.client.api.LdapConnection;
@@ -32,6 +33,9 @@ import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -124,7 +128,6 @@ public abstract class LdapGenericBackend {
public Optional<String> getAttribute(Entry entry, String attName) { public Optional<String> getAttribute(Entry entry, String attName) {
Attribute attribute = entry.get(attName); Attribute attribute = entry.get(attName);
if (attribute == null) { if (attribute == null) {
log.info("DN {}: no attribute {}, skipping", entry.getDn(), attName);
return Optional.empty(); return Optional.empty();
} }
@@ -137,4 +140,22 @@ public abstract class LdapGenericBackend {
return Optional.of(value); return Optional.of(value);
} }
public List<String> getAttributes(Entry entry, String attName) {
List<String> values = new ArrayList<>();
javax.naming.directory.Attribute att = AttributeUtils.toAttributes(entry).get(attName);
if (att == null) {
return values;
}
try {
NamingEnumeration<?> list = att.getAll();
while (list.hasMore()) {
values.add(list.next().toString());
}
} catch (NamingException e) {
log.warn("Error while processing LDAP attribute {}, result could be incomplete!", attName, e);
}
return values;
}
} }

View File

@@ -24,7 +24,7 @@ import io.kamax.matrix._MatrixID;
import io.kamax.mxisd.auth.provider.AuthenticatorProvider; import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
import io.kamax.mxisd.auth.provider.BackendAuthResult; import io.kamax.mxisd.auth.provider.BackendAuthResult;
import io.kamax.mxisd.config.ServerConfig; import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.config.sql.SqlProviderConfig; import io.kamax.mxisd.config.sql.GenericSqlProviderConfig;
import io.kamax.mxisd.invitation.InvitationManager; import io.kamax.mxisd.invitation.InvitationManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -32,15 +32,15 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
public class SqlAuthProvider implements AuthenticatorProvider { public class GenericSqlAuthProvider implements AuthenticatorProvider {
private Logger log = LoggerFactory.getLogger(SqlAuthProvider.class); private Logger log = LoggerFactory.getLogger(GenericSqlAuthProvider.class);
@Autowired @Autowired
private ServerConfig srvCfg; private ServerConfig srvCfg;
@Autowired @Autowired
private SqlProviderConfig cfg; private GenericSqlProviderConfig cfg;
@Autowired @Autowired
private InvitationManager invMgr; private InvitationManager invMgr;

View File

@@ -22,8 +22,8 @@ package io.kamax.mxisd.backend.sql;
import io.kamax.matrix.MatrixID; import io.kamax.matrix.MatrixID;
import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.GenericSqlProviderConfig;
import io.kamax.mxisd.config.sql.SqlConfig; import io.kamax.mxisd.config.sql.SqlConfig;
import io.kamax.mxisd.config.sql.SqlProviderConfig;
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult;
import io.kamax.mxisd.directory.IDirectoryProvider; import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.exception.InternalServerError; import io.kamax.mxisd.exception.InternalServerError;
@@ -39,16 +39,16 @@ import java.util.Optional;
import static io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult.Result; import static io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult.Result;
public abstract class SqlDirectoryProvider implements IDirectoryProvider { public abstract class GenericSqlDirectoryProvider implements IDirectoryProvider {
private Logger log = LoggerFactory.getLogger(SqlDirectoryProvider.class); private Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class);
protected SqlConfig cfg; protected SqlConfig cfg;
private MatrixConfig mxCfg; private MatrixConfig mxCfg;
private SqlConnectionPool pool; private SqlConnectionPool pool;
public SqlDirectoryProvider(SqlConfig cfg, MatrixConfig mxCfg) { public GenericSqlDirectoryProvider(SqlConfig cfg, MatrixConfig mxCfg) {
this.cfg = cfg; this.cfg = cfg;
this.pool = new SqlConnectionPool(cfg); this.pool = new SqlConnectionPool(cfg);
this.mxCfg = mxCfg; this.mxCfg = mxCfg;
@@ -72,7 +72,7 @@ public abstract class SqlDirectoryProvider implements IDirectoryProvider {
return Optional.of(item); return Optional.of(item);
} }
public UserDirectorySearchResult search(String searchTerm, SqlProviderConfig.Query query) { public UserDirectorySearchResult search(String searchTerm, GenericSqlProviderConfig.Query query) {
try (Connection conn = pool.get()) { try (Connection conn = pool.get()) {
log.info("Will execute query: {}", query.getValue()); log.info("Will execute query: {}", query.getValue());
try (PreparedStatement stmt = conn.prepareStatement(query.getValue())) { try (PreparedStatement stmt = conn.prepareStatement(query.getValue())) {

View File

@@ -0,0 +1,36 @@
/*
* 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.backend.sql;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.GenericSqlProviderConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GenericSqlThreePidProvider extends SqlThreePidProvider {
@Autowired
public GenericSqlThreePidProvider(GenericSqlProviderConfig cfg, MatrixConfig mxCfg) {
super(cfg, mxCfg);
}
}

View File

@@ -22,7 +22,7 @@ package io.kamax.mxisd.backend.sql;
import io.kamax.matrix.MatrixID; import io.kamax.matrix.MatrixID;
import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.SqlProviderConfig; import io.kamax.mxisd.config.sql.SqlConfig;
import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest; import io.kamax.mxisd.lookup.SingleLookupRequest;
import io.kamax.mxisd.lookup.ThreePidMapping; import io.kamax.mxisd.lookup.ThreePidMapping;
@@ -30,8 +30,6 @@ import io.kamax.mxisd.lookup.provider.IThreePidProvider;
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;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@@ -41,18 +39,16 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@Component public abstract class SqlThreePidProvider implements IThreePidProvider {
public class SqlThreePidProvider implements IThreePidProvider {
private Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class); private Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class);
private SqlProviderConfig cfg; private SqlConfig cfg;
private MatrixConfig mxCfg; private MatrixConfig mxCfg;
private SqlConnectionPool pool; private SqlConnectionPool pool;
@Autowired public SqlThreePidProvider(SqlConfig cfg, MatrixConfig mxCfg) {
public SqlThreePidProvider(SqlProviderConfig cfg, MatrixConfig mxCfg) {
this.cfg = cfg; this.cfg = cfg;
this.pool = new SqlConnectionPool(cfg); this.pool = new SqlConnectionPool(cfg);
this.mxCfg = mxCfg; this.mxCfg = mxCfg;

View File

@@ -0,0 +1,36 @@
/*
* 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.backend.sql;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SynapseSqlThreePidProvider extends SqlThreePidProvider {
@Autowired
public SynapseSqlThreePidProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) {
super(cfg, mxCfg);
}
}

View File

@@ -21,7 +21,7 @@
package io.kamax.mxisd.backend.sql; package io.kamax.mxisd.backend.sql;
import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.sql.SqlProviderConfig; import io.kamax.mxisd.config.sql.GenericSqlProviderConfig;
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig; import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
import io.kamax.mxisd.exception.ConfigurationException; import io.kamax.mxisd.exception.ConfigurationException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@@ -32,9 +32,7 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
@Component @Component
public class SynapseSqliteDirectoryProvider extends SqlDirectoryProvider { public class SynapseSqliteDirectoryProvider extends GenericSqlDirectoryProvider {
private SynapseSqlProviderConfig cfg;
@Autowired @Autowired
public SynapseSqliteDirectoryProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) { public SynapseSqliteDirectoryProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) {
@@ -42,7 +40,7 @@ public class SynapseSqliteDirectoryProvider extends SqlDirectoryProvider {
if (StringUtils.equals("sqlite", cfg.getType())) { if (StringUtils.equals("sqlite", cfg.getType())) {
String userId = "'@' || p.user_id || ':" + mxCfg.getDomain() + "'"; String userId = "'@' || p.user_id || ':" + mxCfg.getDomain() + "'";
SqlProviderConfig.Type queries = cfg.getDirectory().getQuery(); GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery();
queries.getName().setValue( queries.getName().setValue(
"select " + userId + ", displayname from profiles p where displayname like ?"); "select " + userId + ", displayname from profiles p where displayname like ?");
queries.getThreepid().setValue( queries.getThreepid().setValue(
@@ -51,7 +49,7 @@ public class SynapseSqliteDirectoryProvider extends SqlDirectoryProvider {
"where t.address like ?"); "where t.address like ?");
} else if (StringUtils.equals("postgresql", cfg.getType())) { } else if (StringUtils.equals("postgresql", cfg.getType())) {
String userId = "concat('@',p.user_id,':" + mxCfg.getDomain() + "')"; String userId = "concat('@',p.user_id,':" + mxCfg.getDomain() + "')";
SqlProviderConfig.Type queries = cfg.getDirectory().getQuery(); GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery();
queries.getName().setValue( queries.getName().setValue(
"select " + userId + ", displayname from profiles p where displayname ilike ?"); "select " + userId + ", displayname from profiles p where displayname ilike ?");
queries.getThreepid().setValue( queries.getThreepid().setValue(

View File

@@ -0,0 +1,59 @@
/*
* 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("directory")
public class DirectoryConfig {
private final transient Logger log = LoggerFactory.getLogger(DnsOverwriteConfig.class);
public static class Exclude {
private boolean homeserver;
public boolean getHomeserver() {
return homeserver;
}
public Exclude setHomeserver(boolean homeserver) {
this.homeserver = homeserver;
return this;
}
}
private Exclude exclude = new Exclude();
public Exclude getExclude() {
return exclude;
}
public void setExclude(Exclude exclude) {
this.exclude = exclude;
}
}

View File

@@ -24,21 +24,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import javax.annotation.PostConstruct;
@Configuration @Configuration
@ConfigurationProperties("sql") @ConfigurationProperties("sql")
@Primary @Primary
public class SqlProviderConfig extends SqlConfig { public class GenericSqlProviderConfig extends SqlConfig {
@Override @Override
protected String getProviderName() { protected String getProviderName() {
return "Generic SQL"; return "Generic SQL";
} }
@PostConstruct
public void build() {
super.build();
}
} }

View File

@@ -4,6 +4,7 @@ import io.kamax.mxisd.util.GsonUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -36,22 +37,22 @@ public abstract class SqlConfig {
public static class Type { public static class Type {
private SqlProviderConfig.Query name = new SqlProviderConfig.Query(); private GenericSqlProviderConfig.Query name = new GenericSqlProviderConfig.Query();
private SqlProviderConfig.Query threepid = new SqlProviderConfig.Query(); private GenericSqlProviderConfig.Query threepid = new GenericSqlProviderConfig.Query();
public SqlProviderConfig.Query getName() { public GenericSqlProviderConfig.Query getName() {
return name; return name;
} }
public void setName(SqlProviderConfig.Query name) { public void setName(GenericSqlProviderConfig.Query name) {
this.name = name; this.name = name;
} }
public SqlProviderConfig.Query getThreepid() { public GenericSqlProviderConfig.Query getThreepid() {
return threepid; return threepid;
} }
public void setThreepid(SqlProviderConfig.Query threepid) { public void setThreepid(GenericSqlProviderConfig.Query threepid) {
this.threepid = threepid; this.threepid = threepid;
} }
@@ -74,7 +75,7 @@ public abstract class SqlConfig {
public static class Directory { public static class Directory {
private Boolean enabled; private Boolean enabled;
private SqlProviderConfig.Type query = new SqlProviderConfig.Type(); private GenericSqlProviderConfig.Type query = new GenericSqlProviderConfig.Type();
public Boolean isEnabled() { public Boolean isEnabled() {
return enabled; return enabled;
@@ -84,11 +85,11 @@ public abstract class SqlConfig {
this.enabled = enabled; this.enabled = enabled;
} }
public SqlProviderConfig.Type getQuery() { public GenericSqlProviderConfig.Type getQuery() {
return query; return query;
} }
public void setQuery(SqlProviderConfig.Type query) { public void setQuery(GenericSqlProviderConfig.Type query) {
this.query = query; this.query = query;
} }
@@ -138,9 +139,9 @@ public abstract class SqlConfig {
private boolean enabled; private boolean enabled;
private String type; private String type;
private String connection; private String connection;
private SqlProviderConfig.Auth auth = new SqlProviderConfig.Auth(); private GenericSqlProviderConfig.Auth auth = new GenericSqlProviderConfig.Auth();
private SqlProviderConfig.Directory directory = new SqlProviderConfig.Directory(); private GenericSqlProviderConfig.Directory directory = new GenericSqlProviderConfig.Directory();
private SqlProviderConfig.Identity identity = new SqlProviderConfig.Identity(); private GenericSqlProviderConfig.Identity identity = new GenericSqlProviderConfig.Identity();
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
@@ -166,35 +167,33 @@ public abstract class SqlConfig {
this.connection = connection; this.connection = connection;
} }
public SqlProviderConfig.Auth getAuth() { public GenericSqlProviderConfig.Auth getAuth() {
return auth; return auth;
} }
public void setAuth(SqlProviderConfig.Auth auth) { public void setAuth(GenericSqlProviderConfig.Auth auth) {
this.auth = auth; this.auth = auth;
} }
public SqlProviderConfig.Directory getDirectory() { public GenericSqlProviderConfig.Directory getDirectory() {
return directory; return directory;
} }
public void setDirectory(SqlProviderConfig.Directory directory) { public void setDirectory(GenericSqlProviderConfig.Directory directory) {
this.directory = directory; this.directory = directory;
} }
public SqlProviderConfig.Identity getIdentity() { public GenericSqlProviderConfig.Identity getIdentity() {
return identity; return identity;
} }
public void setIdentity(SqlProviderConfig.Identity identity) { public void setIdentity(GenericSqlProviderConfig.Identity identity) {
this.identity = identity; this.identity = identity;
} }
protected abstract String getProviderName(); protected abstract String getProviderName();
public void build() { protected void doBuild() {
log.info("--- " + getProviderName() + " Provider config ---");
if (getAuth().isEnabled() == null) { if (getAuth().isEnabled() == null) {
getAuth().setEnabled(isEnabled()); getAuth().setEnabled(isEnabled());
} }
@@ -206,6 +205,13 @@ public abstract class SqlConfig {
if (getIdentity().isEnabled() == null) { if (getIdentity().isEnabled() == null) {
getIdentity().setEnabled(isEnabled()); getIdentity().setEnabled(isEnabled());
} }
}
@PostConstruct
public void build() {
log.info("--- " + getProviderName() + " Provider config ---");
doBuild();
log.info("Enabled: {}", isEnabled()); log.info("Enabled: {}", isEnabled());
if (isEnabled()) { if (isEnabled()) {
@@ -214,6 +220,7 @@ public abstract class SqlConfig {
log.info("Auth enabled: {}", getAuth().isEnabled()); log.info("Auth enabled: {}", getAuth().isEnabled());
log.info("Directory queries: {}", GsonUtil.build().toJson(getDirectory().getQuery())); log.info("Directory queries: {}", GsonUtil.build().toJson(getDirectory().getQuery()));
log.info("Identity type: {}", getIdentity().getType()); log.info("Identity type: {}", getIdentity().getType());
log.info("3PID mapping query: {}", getIdentity().getQuery());
log.info("Identity medium queries: {}", GsonUtil.build().toJson(getIdentity().getMedium())); log.info("Identity medium queries: {}", GsonUtil.build().toJson(getIdentity().getMedium()));
} }
} }

View File

@@ -21,6 +21,7 @@
package io.kamax.mxisd.config.sql.synapse; package io.kamax.mxisd.config.sql.synapse;
import io.kamax.mxisd.config.sql.SqlConfig; import io.kamax.mxisd.config.sql.SqlConfig;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -36,8 +37,23 @@ public class SynapseSqlProviderConfig extends SqlConfig {
} }
@PostConstruct @PostConstruct
public void build() { public void doBuild() {
super.build(); super.doBuild();
// FIXME check that the DB is not the mxisd one
// See https://matrix.to/#/!NPRUEisLjcaMtHIzDr:kamax.io/$1509377583327omXkC:kamax.io
getAuth().setEnabled(false); // Synapse does the auth, we only act as a directory/identity service.
if (getDirectory().isEnabled()) {
//FIXME set default queries for name and threepid
}
if (getIdentity().isEnabled()) {
if (StringUtils.isBlank(getIdentity().getType())) {
getIdentity().setType("mxid");
getIdentity().setQuery("SELECT user_id AS uid FROM user_threepids WHERE medium = ? AND address = ?");
}
}
} }
} }

View File

@@ -23,6 +23,7 @@ package io.kamax.mxisd.directory;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import io.kamax.matrix.MatrixErrorInfo; import io.kamax.matrix.MatrixErrorInfo;
import io.kamax.mxisd.config.DirectoryConfig;
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest; import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest;
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult; import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult;
import io.kamax.mxisd.dns.ClientDnsOverwrite; import io.kamax.mxisd.dns.ClientDnsOverwrite;
@@ -54,6 +55,7 @@ public class DirectoryManager {
private Logger log = LoggerFactory.getLogger(DirectoryManager.class); private Logger log = LoggerFactory.getLogger(DirectoryManager.class);
private DirectoryConfig cfg;
private List<IDirectoryProvider> providers; private List<IDirectoryProvider> providers;
private ClientDnsOverwrite dns; private ClientDnsOverwrite dns;
@@ -61,7 +63,8 @@ public class DirectoryManager {
private Gson gson; private Gson gson;
@Autowired @Autowired
public DirectoryManager(List<IDirectoryProvider> providers, ClientDnsOverwrite dns) { public DirectoryManager(DirectoryConfig cfg, List<IDirectoryProvider> providers, ClientDnsOverwrite dns) {
this.cfg = cfg;
this.dns = dns; this.dns = dns;
this.client = HttpClients.custom().setUserAgent("mxisd").build(); //FIXME centralize this.client = HttpClients.custom().setUserAgent("mxisd").build(); //FIXME centralize
this.gson = GsonUtil.build(); this.gson = GsonUtil.build();
@@ -76,6 +79,9 @@ public class DirectoryManager {
log.info("Original request URL: {}", target); log.info("Original request URL: {}", target);
UserDirectorySearchResult result = new UserDirectorySearchResult(); UserDirectorySearchResult result = new UserDirectorySearchResult();
if (cfg.getExclude().getHomeserver()) {
log.info("Skipping HS directory data, disabled in config");
} else {
URIBuilder builder = dns.transform(target); URIBuilder builder = dns.transform(target);
log.info("Querying HS at {}", builder); log.info("Querying HS at {}", builder);
builder.setParameter("access_token", accessToken); builder.setParameter("access_token", accessToken);
@@ -108,6 +114,7 @@ public class DirectoryManager {
} catch (IOException e) { } catch (IOException e) {
throw new InternalServerError("Unable to query the HS: I/O error: " + e.getMessage()); throw new InternalServerError("Unable to query the HS: I/O error: " + e.getMessage());
} }
}
for (IDirectoryProvider provider : providers) { for (IDirectoryProvider provider : providers) {
log.info("Using Directory provider {}", provider.getClass().getSimpleName()); log.info("Using Directory provider {}", provider.getClass().getSimpleName());

View File

@@ -53,7 +53,10 @@ public class RecursivePriorityLookupStrategy implements LookupStrategy {
public RecursivePriorityLookupStrategy(RecursiveLookupConfig cfg, List<IThreePidProvider> providers, IBridgeFetcher bridge) { public RecursivePriorityLookupStrategy(RecursiveLookupConfig cfg, List<IThreePidProvider> providers, IBridgeFetcher bridge) {
this.cfg = cfg; this.cfg = cfg;
this.bridge = bridge; this.bridge = bridge;
this.providers = providers.stream().filter(IThreePidProvider::isEnabled).collect(Collectors.toList()); this.providers = providers.stream().filter(p -> {
log.info("3PID Provider {} is enabled: {}", p.getClass().getSimpleName(), p.isEnabled());
return p.isEnabled();
}).collect(Collectors.toList());
} }
@PostConstruct @PostConstruct

View File

@@ -227,6 +227,10 @@ view:
storage: storage:
backend: 'sqlite' backend: 'sqlite'
directory:
exclude:
homeserver: false
--- ---
spring: spring:
profiles: systemd profiles: systemd