Compare commits

...

6 Commits
v1.0.1 ... v1.1

Author SHA1 Message Date
Max Dor
f55d5fbc80 Make central IS opt-in (#80) 2018-05-31 13:24:00 +02:00
Max Dor
b613415dc4 Fix doc layout (cosmetic) 2018-05-18 01:47:43 +02:00
Max Dor
0549d23d21 Add LDAP TLS config value in logs 2018-05-16 15:42:24 +02:00
Max Dor
b493ccd479 De-duplicate results from Identity stores in Directory searches 2018-04-26 01:45:04 +02:00
Max Dor
03e72ba155 Use the correct domain (server name) for signatures 2018-04-22 19:27:52 +02:00
Max Dor
32a3444a9e Document the correct property for SQL usernames 2018-04-22 00:39:18 +02:00
14 changed files with 110 additions and 62 deletions

View File

@@ -47,18 +47,33 @@ key.path: ''
storage.provider.sqlite.database: '/path/to/mxisd.db' storage.provider.sqlite.database: '/path/to/mxisd.db'
####################
# Fallback servers #
####################
#
# Root/Central servers to be used as final fallback when performing lookups.
# By default, for privacy reasons, matrix.org servers are not enabled anymore.
# See the following issue: https://github.com/kamax-io/mxisd/issues/76
#
# If you would like to use them and trade away your privacy for convenience, uncomment the following option:
#
#forward.servers: ['matrix-org']
################ ################
# LDAP Backend # # LDAP Backend #
################ ################
# If you would like to integrate with your AD/Samba/LDAP server, # If you would like to integrate with your AD/Samba/LDAP server,
# see https://github.com/kamax-io/mxisd/blob/master/docs/backends/ldap.md # see https://github.com/kamax-io/mxisd/blob/master/docs/backends/ldap.md
############### ###############
# SQL Backend # # SQL Backend #
############### ###############
# If you would like to integrate with a MySQL/MariaDB/PostgreQL/SQLite DB, # If you would like to integrate with a MySQL/MariaDB/PostgreQL/SQLite DB,
# see https://github.com/kamax-io/mxisd/blob/master/docs/backends/sql.md # see https://github.com/kamax-io/mxisd/blob/master/docs/backends/sql.md
################ ################
# REST Backend # # REST Backend #
################ ################

View File

@@ -18,12 +18,9 @@ TCP 443
| +-------------------+ | +-------------------+
TCP 8090 +-> | mxisd | TCP 8090 +-> | mxisd |
| | | |
| - Profile's 3PIDs >----+ | - Profile's 3PIDs |
| - 3PID Invites | | +--------------------------+ | - 3PID Invites |
+-|-----------------+ +>----------> | Central Identity service | +-|-----------------+
| | TCP 443 | Matrix.org / Vector.im |
| | +--------------------------+
+>-------------------->+
| |
TCP 443 TCP 443
| +------------------------+ | +------------------------+

View File

@@ -19,8 +19,9 @@ started and answer questions you might have.
### Do I need to use mxisd if I run a Homeserver? ### Do I need to use mxisd if I run a Homeserver?
No, but it is strongly recommended, even if you don't use any Identity store or integration. No, but it is strongly recommended, even if you don't use any Identity store or integration.
In its default configuration, mxisd will talk to the central Matrix Identity servers and use other federated public In its default configuration, mxisd uses other federated public servers when performing queries.
servers when performing queries, giving you access to at least the same information as if you were not running it. It can also [be configured](features/identity.md#lookups) to use the central matrix.org servers, giving you access to at
least the same information as if you were not running it.
It will also give your users a choice to make their 3PIDs available publicly, ensuring they are made aware of the It will also give your users a choice to make their 3PIDs available publicly, ensuring they are made aware of the
privacy consequences, which is not the case with the central Matrix.org servers. privacy consequences, which is not the case with the central Matrix.org servers.
@@ -70,18 +71,15 @@ So really, you should go with mxisd.
### Will I loose access to the central Matrix.org/Vector.im Identity data if I use mxisd? ### Will I loose access to the central Matrix.org/Vector.im Identity data if I use mxisd?
No. No.
In its default configuration, mxisd act as a proxy to Matrix.org/Vector.im. You will have access to the same data and In its default configuration, mxisd does not talk to the central Identity server matrix.org to avoid leaking your private
behaviour than if you were using them directly. There is no downside in using mxisd with the default configuration. data and those of people you might know.
mxisd can also be configured not to talk to the central Identity servers if you wish. mxisd [can be configured](features/identity.md#lookups) to talk to the central Identity servers if you wish.
### So mxisd is just a big hack! I don't want to use non-official features! ### So mxisd is just a big hack! I don't want to use non-official features!
mxisd primary concern is to always be compatible with the Matrix ecosystem and the Identity service API. mxisd primary concerns are your privacy and to always be compatible with the Matrix ecosystem and the Identity service API.
Whenever the API will be updated and/or enhanced, mxisd will follow, remaining 100% compatible with the ecosystem. Whenever the API will be updated and/or enhanced, mxisd will follow, remaining 100% compatible with the ecosystem.
Therefore, using mxisd is a safe choice. It will be like using the central Matrix.org Identity servers, yet not closing
the door to a growing list of enhancements and integrations.
### Should I use mxisd if I don't host my own Homeserver? ### Should I use mxisd if I don't host my own Homeserver?
No. No.

View File

@@ -5,8 +5,8 @@ Federated Identity server using the DNS domain part of the 3PID.
Emails are the best candidate for this kind of resolution which are DNS domain based already. Emails are the best candidate for this kind of resolution which are DNS domain based already.
On the other hand, Phone numbers cannot be resolved this way. On the other hand, Phone numbers cannot be resolved this way.
For 3PIDs which are not compatible with the DNS system, mxisd will talk to the central Identity server of matrix.org by For 3PIDs which are not compatible with the DNS system, mxisd can be configured to talk to fallback Identity servers like
default. the central matrix.org one. See the [Identity feature](identity.md#lookups) for instructions on how to enable it.
Outbound federation is enabled by default while inbound federation is opt-in and require a specific DNS record. Outbound federation is enabled by default while inbound federation is opt-in and require a specific DNS record.
@@ -17,16 +17,14 @@ Outbound federation is enabled by default while inbound federation is opt-in and
| | | +------> +----------+ | | | +------> +----------+
| | | | | | | |
| Invites / Lookups | | | | Invites / Lookups | | |
Federated | +--------+ | | | +-------------------+ Federated | +--------+ | | |
Identity ---->| Remote |>-----------+ +------> | Remote Federated | Identity ---->| Remote |>-----------+ |
Server | +--------+ | | | mxisd servers | Server | +--------+ | |
| | | +-------------------+ | | |
| +--------+ | | | +--------+ | | +-------------------+
Homeserver --->| Local |>------------------+ Homeserver --->| Local |>------------------+------> | Remote Federated |
and clients | +--------+ | | +--------------------------+ and clients | +--------+ | | mxisd servers |
+-------------------+ +------> | Central Identity service | +-------------------+ +-------------------+
| Matrix.org / Vector.im |
+--------------------------+
``` ```
## Inbound ## Inbound

View File

@@ -3,6 +3,16 @@
Implementation of the [Unofficial Matrix Identity Service API](https://kamax.io/matrix/api/identity_service/unstable.html). Implementation of the [Unofficial Matrix Identity Service API](https://kamax.io/matrix/api/identity_service/unstable.html).
## Lookups
If you would like to use the central matrix.org Identity server to ensure maximum discovery at the cost of potentially
leaking all your contacts information, add the following to your configuration:
```yaml
forward.servers:
- 'matrix-org'
```
**NOTE:** You should carefully consider enabling this option, which is discouraged.
For more info, see the [relevant issue](https://github.com/kamax-io/mxisd/issues/76).
## Room Invitations ## Room Invitations
Resolution can be customized using the following configuration: Resolution can be customized using the following configuration:

View File

@@ -44,7 +44,7 @@ Example: `/path/to/sqlite/file.db`
#### Others #### Others
```yaml ```yaml
sql.connection: //<HOST[:PORT]/DB?username=USER&password=PASS sql.connection: //<HOST[:PORT]/DB?user=USER&password=PASS
``` ```
Set the connection info for the database by replacing the following values: Set the connection info for the database by replacing the following values:
- `HOST`: Hostname of the SQL server - `HOST`: Hostname of the SQL server

View File

@@ -35,7 +35,7 @@ Example: `/path/to/synapse/sqliteFile.db`
### PostgreSQL ### PostgreSQL
```yaml ```yaml
synapseSql.connection: //<HOST[:PORT]/DB?username=USER&password=PASS synapseSql.connection: //<HOST[:PORT]/DB?user=USER&password=PASS
``` ```
Set the connection info for the database by replacing the following values: Set the connection info for the database by replacing the following values:
- `HOST`: Hostname of the SQL server - `HOST`: Hostname of the SQL server

View File

@@ -117,6 +117,7 @@ The following example of configuration (incomplete extract) shows which items ar
**IMPORTANT:** Most configuration items shown have default values and should not be included in your own configuration **IMPORTANT:** Most configuration items shown have default values and should not be included in your own configuration
file unless you want to specifically overwrite them. file unless you want to specifically overwrite them.
```yaml ```yaml
# CONFIGURATION EXAMPLE
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION # DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
session.policy.validation.enabled: true session.policy.validation.enabled: true
session.policy.validation.forLocal: session.policy.validation.forLocal:
@@ -132,6 +133,7 @@ session.policy.validation.forRemote:
enabled: true enabled: true
server: 'configExample' # Not to be included in config! Already present in default config! server: 'configExample' # Not to be included in config! Already present in default config!
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION # DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
# CONFIGURATION EXAMPLE
``` ```
`session.policy.validation` is the core configuration to control what users configured to use your Identity server `session.policy.validation` is the core configuration to control what users configured to use your Identity server
@@ -144,7 +146,7 @@ Each scope is divided into three parts:
- global on/off switch for 3PID sessions using `.enabled` - global on/off switch for 3PID sessions using `.enabled`
- `toLocal` allowing or not local 3PID session validations - `toLocal` allowing or not local 3PID session validations
- `toRemote` allowing or not remote 3PID session validations and to which server such sessions should be sent. - `toRemote` allowing or not remote 3PID session validations and to which server such sessions should be sent.
`.server` takes a Matrix Identity server list label. Only the first server in the list is currently used. `.server` takes a Matrix Identity server list label. Only the first server in the list is currently used.
If both `toLocal` and `toRemote` are enabled, the user will be offered to initiate a remote session once their 3PID If both `toLocal` and `toRemote` are enabled, the user will be offered to initiate a remote session once their 3PID
locally validated. locally validated.

View File

@@ -359,6 +359,7 @@ public abstract class LdapConfig {
log.info("Host: {}", connection.getHost()); log.info("Host: {}", connection.getHost());
log.info("Port: {}", connection.getPort()); log.info("Port: {}", connection.getPort());
log.info("TLS: {}", connection.isTls());
log.info("Bind DN: {}", connection.getBindDn()); log.info("Bind DN: {}", connection.getBindDn());
log.info("Base DN: {}", connection.getBaseDn()); log.info("Base DN: {}", connection.getBaseDn());

View File

@@ -20,8 +20,8 @@
package io.kamax.mxisd.controller.directory.v1.io; package io.kamax.mxisd.controller.directory.v1.io;
import java.util.ArrayList; import java.util.HashSet;
import java.util.List; import java.util.Set;
public class UserDirectorySearchResult { public class UserDirectorySearchResult {
@@ -55,10 +55,31 @@ public class UserDirectorySearchResult {
this.userId = userId; this.userId = userId;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Result result = (Result) o;
if (displayName != null ? !displayName.equals(result.displayName) : result.displayName != null)
return false;
if (avatarUrl != null ? !avatarUrl.equals(result.avatarUrl) : result.avatarUrl != null) return false;
return userId.equals(result.userId);
}
@Override
public int hashCode() {
int result = displayName != null ? displayName.hashCode() : 0;
result = 31 * result + (avatarUrl != null ? avatarUrl.hashCode() : 0);
result = 31 * result + userId.hashCode();
return result;
}
} }
private boolean limited; private boolean limited;
private List<Result> results = new ArrayList<>(); private Set<Result> results = new HashSet<>();
public boolean isLimited() { public boolean isLimited() {
return limited; return limited;
@@ -68,11 +89,11 @@ public class UserDirectorySearchResult {
this.limited = limited; this.limited = limited;
} }
public List<Result> getResults() { public Set<Result> getResults() {
return results; return results;
} }
public void setResults(List<Result> results) { public void setResults(Set<Result> results) {
this.results = results; this.results = results;
} }

View File

@@ -21,6 +21,7 @@
package io.kamax.mxisd.lookup.provider; package io.kamax.mxisd.lookup.provider;
import io.kamax.mxisd.config.ForwardConfig; import io.kamax.mxisd.config.ForwardConfig;
import io.kamax.mxisd.config.MatrixConfig;
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;
@@ -42,6 +43,9 @@ class ForwarderProvider implements IThreePidProvider {
@Autowired @Autowired
private ForwardConfig cfg; private ForwardConfig cfg;
@Autowired
private MatrixConfig mxCfg;
@Autowired @Autowired
private IRemoteIdentityServerFetcher fetcher; private IRemoteIdentityServerFetcher fetcher;
@@ -62,12 +66,15 @@ class ForwarderProvider implements IThreePidProvider {
@Override @Override
public Optional<SingleLookupReply> find(SingleLookupRequest request) { public Optional<SingleLookupReply> find(SingleLookupRequest request) {
for (String root : cfg.getServers()) { for (String label : cfg.getServers()) {
Optional<SingleLookupReply> answer = fetcher.find(root, request); for (String srv : mxCfg.getIdentity().getServers(label)) {
log.info("Using forward server {}", srv);
Optional<SingleLookupReply> answer = fetcher.find(srv, request);
if (answer.isPresent()) { if (answer.isPresent()) {
return answer; return answer;
} }
} }
}
return Optional.empty(); return Optional.empty();
} }
@@ -77,14 +84,16 @@ class ForwarderProvider implements IThreePidProvider {
List<ThreePidMapping> mappingsToDo = new ArrayList<>(mappings); List<ThreePidMapping> mappingsToDo = new ArrayList<>(mappings);
List<ThreePidMapping> mappingsFoundGlobal = new ArrayList<>(); List<ThreePidMapping> mappingsFoundGlobal = new ArrayList<>();
for (String root : cfg.getServers()) { for (String label : cfg.getServers()) {
for (String srv : mxCfg.getIdentity().getServers(label)) {
log.info("{} mappings remaining: {}", mappingsToDo.size(), mappingsToDo); log.info("{} mappings remaining: {}", mappingsToDo.size(), mappingsToDo);
log.info("Querying {}", root); log.info("Querying {}", srv);
List<ThreePidMapping> mappingsFound = fetcher.find(root, mappingsToDo); List<ThreePidMapping> mappingsFound = fetcher.find(srv, mappingsToDo);
log.info("{} returned {} mappings", root, mappingsFound.size()); log.info("{} returned {} mappings", srv, mappingsFound.size());
mappingsFoundGlobal.addAll(mappingsFound); mappingsFoundGlobal.addAll(mappingsFound);
mappingsToDo.removeAll(mappingsFound); mappingsToDo.removeAll(mappingsFound);
} }
}
return mappingsFoundGlobal; return mappingsFoundGlobal;
} }

View File

@@ -24,7 +24,7 @@ import io.kamax.matrix.crypto.KeyFileStore;
import io.kamax.matrix.crypto.KeyManager; import io.kamax.matrix.crypto.KeyManager;
import io.kamax.matrix.crypto.SignatureManager; import io.kamax.matrix.crypto.SignatureManager;
import io.kamax.mxisd.config.KeyConfig; import io.kamax.mxisd.config.KeyConfig;
import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ServerConfig;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -50,8 +50,8 @@ public class CryptoFactory {
} }
@Bean @Bean
public SignatureManager getSignatureManager(KeyManager keyMgr, MatrixConfig mxCfg) { public SignatureManager getSignatureManager(KeyManager keyMgr, ServerConfig cfg) {
return new SignatureManager(keyMgr, mxCfg.getDomain()); return new SignatureManager(keyMgr, cfg.getName());
} }
} }

View File

@@ -24,7 +24,7 @@ matrix:
domain: '' domain: ''
identity: identity:
servers: servers:
root: matrix-org:
- 'https://matrix.org' - 'https://matrix.org'
lookup: lookup:
@@ -174,9 +174,7 @@ wordpress:
threepid: 'SELECT DISTINCT user_login, display_name FROM wp_users WHERE user_email LIKE ?' threepid: 'SELECT DISTINCT user_login, display_name FROM wp_users WHERE user_email LIKE ?'
forward: forward:
servers: servers: []
- 'https://matrix.org'
- 'https://vector.im'
threepid: threepid:
medium: medium:
@@ -226,13 +224,13 @@ session:
toLocal: true toLocal: true
toRemote: toRemote:
enabled: true enabled: true
server: 'root' server: 'matrix-org'
forRemote: forRemote:
enabled: true enabled: true
toLocal: false toLocal: false
toRemote: toRemote:
enabled: true enabled: true
server: 'root' server: 'matrix-org'
notification: notification:
# handler: # handler:

View File

@@ -33,8 +33,7 @@ import org.junit.Test;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
public class RestDirectoryProviderTest { public class RestDirectoryProviderTest {
@@ -89,8 +88,8 @@ public class RestDirectoryProviderTest {
UserDirectorySearchResult result = p.searchByDisplayName(byNameSearch); UserDirectorySearchResult result = p.searchByDisplayName(byNameSearch);
assertTrue(!result.isLimited()); assertTrue(!result.isLimited());
assertTrue(result.getResults().size() == 1); assertEquals(1, result.getResults().size());
UserDirectorySearchResult.Result entry = result.getResults().get(0); UserDirectorySearchResult.Result entry = result.getResults().iterator().next();
assertNotNull(entry); assertNotNull(entry);
assertTrue(StringUtils.equals(byNameAvatar, entry.getAvatarUrl())); assertTrue(StringUtils.equals(byNameAvatar, entry.getAvatarUrl()));
assertTrue(StringUtils.equals(byNameDisplay, entry.getDisplayName())); assertTrue(StringUtils.equals(byNameDisplay, entry.getDisplayName()));
@@ -132,8 +131,8 @@ public class RestDirectoryProviderTest {
UserDirectorySearchResult result = p.searchBy3pid(byThreepidSearch); UserDirectorySearchResult result = p.searchBy3pid(byThreepidSearch);
assertTrue(!result.isLimited()); assertTrue(!result.isLimited());
assertTrue(result.getResults().size() == 1); assertEquals(1, result.getResults().size());
UserDirectorySearchResult.Result entry = result.getResults().get(0); UserDirectorySearchResult.Result entry = result.getResults().iterator().next();
assertNotNull(entry); assertNotNull(entry);
assertTrue(StringUtils.equals(byThreepidAvatar, entry.getAvatarUrl())); assertTrue(StringUtils.equals(byThreepidAvatar, entry.getAvatarUrl()));
assertTrue(StringUtils.equals(byThreepidDisplay, entry.getDisplayName())); assertTrue(StringUtils.equals(byThreepidDisplay, entry.getDisplayName()));