diff --git a/README.md b/README.md index 94ccf11..40e325b 100644 --- a/README.md +++ b/README.md @@ -169,11 +169,14 @@ systemctl start mxisd # Configuration After following the specific instructions to create a config file from the sample: -1. Set the `server.name` value to the domain value used in your Home Server configuration +1. Set the `matrix.domain` value to the domain value used in your Home Server configuration 2. Set an absolute location for the signing keys using `key.path` 3. Set a location for the default SQLite persistence using `storage.provider.sqlite.database` 4. Configure the E-mail invite sender with items starting in `invite.sender.email` +In case your IS public domain does not match your Matrix domain, see `server.name` and `server.publicUrl` +config items. + If you want to use the LDAP backend: 1. Enable it with `ldap.enabled` 2. Configure connection options using items starting in `ldap.connection` diff --git a/application.example.yaml b/application.example.yaml index bf78495..a52d1f4 100644 --- a/application.example.yaml +++ b/application.example.yaml @@ -7,6 +7,15 @@ # Any mandatory configuration item will not be prefixed by # and will also contain a value as example that must be # changed. It is advised to re-create a clean config file with only the required configuration item. +####################### +# Matrix config items # +####################### +# Matrix domain, same as the domain configure in your Homeserver configuration. +# +# This is used to build the various identifiers for identity, auth and directory. +matrix.domain: '' + + ####################### # Server config items # @@ -19,21 +28,33 @@ #server.port: 8090 -# Realm under which this Identity Server is authoritative. +# Public hostname of this identity server. # -# This is used to avoid unnecessary connections and endless recursive lookup. -# e.g. domain name in e-mails. -server.name: 'example.org' +# This would be typically be the same as your Matrix domain. +# In case it is not, set this value. +# +# This value is used in various signatures within the Matrix protocol and should be a reachable hostname. +# You can validate by ensuring you see a JSON answer when calling (replace the domain): +# https://example.org/_matrix/identity/status +# +#server.name: 'example.org' # Public URL to reach this identity server # # This is used with 3PID invites in room and other Homeserver key verification workflow. -# If left unconfigured, it will be generated from the server name +# If left unconfigured, it will be generated from the server name. +# +# You should typically set this value if you want to change the public port under which +# this Identity server is reachable. +# +# %SERVER_NAME% placeholder is available to avoid configuration duplication. +# e.g. 'https://%SERVER_NAME%:8443' # #server.publicUrl: 'https://example.org' + ############################# # Signing keys config items # ############################# @@ -47,6 +68,7 @@ server.name: 'example.org' key.path: '/path/to/sign.key' + ################################# # Recurisve lookup config items # ################################# @@ -125,14 +147,15 @@ key.path: '/path/to/sign.key' #lookup.recursive.bridge.mappings.msisdn: '' + ##################### # LDAP config items # ##################### - # Global enable/disable switch # #ldap.enabled: false + #### Connection related config items # If the connection should be secure # @@ -223,6 +246,7 @@ key.path: '/path/to/sign.key' #ldap.identity.medium.msisdn: "(|(telephoneNumber=+%3pid)(mobile=+%3pid)(homePhone=+%3pid)(otherTelephone=+%3pid)(otherMobile=+%3pid)(otherHomePhone=+%3pid))" + ############################ # SQL Provider config item # ############################ @@ -251,6 +275,7 @@ key.path: '/path/to/sign.key' # - "https://vector.im" + ############################# # 3PID invites config items # ############################# @@ -319,6 +344,7 @@ invite.sender.email.email: "matrix-identity@example.org" #invite.sender.email.template: "/absolute/path/to/file" + ############################ # Persistence config items # ############################ @@ -329,6 +355,7 @@ invite.sender.email.email: "matrix-identity@example.org" # #storage.backend: 'sqlite' + #### Generic SQLite provider config # # Path to the SQLite DB file, required if SQLite backend is chosen @@ -341,6 +368,7 @@ invite.sender.email.email: "matrix-identity@example.org" storage.provider.sqlite.database: '/path/to/mxisd.db' + ###################### # DNS-related config # ###################### @@ -348,11 +376,13 @@ storage.provider.sqlite.database: '/path/to/mxisd.db' # #dns.overwrite.homeserver.name: 'example.org' + # - 'env' from environment variable specified by value # - any other value will use the value as-is as host # #dns.overwrite.homeserver.type: 'raw' + # The value to use, depending on the type # #dns.overwrite.homeserver.value: 'localhost:8448' diff --git a/src/main/groovy/io/kamax/mxisd/config/FirebaseConfig.java b/src/main/groovy/io/kamax/mxisd/config/FirebaseConfig.java index b3799f8..52f6f77 100644 --- a/src/main/groovy/io/kamax/mxisd/config/FirebaseConfig.java +++ b/src/main/groovy/io/kamax/mxisd/config/FirebaseConfig.java @@ -40,7 +40,7 @@ public class FirebaseConfig { private Logger log = LoggerFactory.getLogger(FirebaseConfig.class); @Autowired - private ServerConfig srvCfg; + private MatrixConfig mxCfg; private boolean enabled; private String credentials; @@ -85,7 +85,7 @@ public class FirebaseConfig { if (!enabled) { return new GoogleFirebaseAuthenticator(false); } else { - return new GoogleFirebaseAuthenticator(credentials, database, srvCfg.getName()); + return new GoogleFirebaseAuthenticator(credentials, database, mxCfg.getDomain()); } } @@ -94,7 +94,7 @@ public class FirebaseConfig { if (!enabled) { return new GoogleFirebaseProvider(false); } else { - return new GoogleFirebaseProvider(credentials, database, srvCfg.getName()); + return new GoogleFirebaseProvider(credentials, database, mxCfg.getDomain()); } } diff --git a/src/main/groovy/io/kamax/mxisd/config/MatrixConfig.java b/src/main/groovy/io/kamax/mxisd/config/MatrixConfig.java new file mode 100644 index 0000000..c6cfd2d --- /dev/null +++ b/src/main/groovy/io/kamax/mxisd/config/MatrixConfig.java @@ -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 . + */ + +package io.kamax.mxisd.config; + +import io.kamax.mxisd.exception.ConfigurationException; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; + +@Configuration +@ConfigurationProperties("matrix") +public class MatrixConfig { + + private Logger log = LoggerFactory.getLogger(MatrixConfig.class); + + private String domain; + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + @PostConstruct + private void postConstruct() { + log.info("--- Matrix config ---"); + + if (StringUtils.isBlank(domain)) { + throw new ConfigurationException("matrix.domain"); + } + + log.info("Domain: {}", getDomain()); + } + +} diff --git a/src/main/groovy/io/kamax/mxisd/config/ServerConfig.groovy b/src/main/groovy/io/kamax/mxisd/config/ServerConfig.groovy index d29b4ce..0db57b2 100644 --- a/src/main/groovy/io/kamax/mxisd/config/ServerConfig.groovy +++ b/src/main/groovy/io/kamax/mxisd/config/ServerConfig.groovy @@ -20,11 +20,11 @@ package io.kamax.mxisd.config -import io.kamax.mxisd.exception.ConfigurationException import org.apache.commons.lang.StringUtils import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.InitializingBean +import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.context.annotation.Configuration @@ -34,6 +34,9 @@ class ServerConfig implements InitializingBean { private Logger log = LoggerFactory.getLogger(ServerConfig.class); + @Autowired + private MatrixConfig mxCfg; + private String name private int port private String publicUrl @@ -64,13 +67,18 @@ class ServerConfig implements InitializingBean { @Override void afterPropertiesSet() throws Exception { + log.info("--- Server config ---") + if (StringUtils.isBlank(getName())) { - throw new ConfigurationException("server.name") + setName(mxCfg.getDomain()); + log.debug("server.name is empty, using matrix.domain"); } if (StringUtils.isBlank(getPublicUrl())) { - log.warn("Public URL is empty, generating from name {}", getName()) - publicUrl = "https://${getName()}" + setPublicUrl("https://${getName()}"); + log.debug("Public URL is empty, generating from name"); + } else { + setPublicUrl(StringUtils.replace(getPublicUrl(), "%SERVER_NAME%", getName())); } try { @@ -79,7 +87,6 @@ class ServerConfig implements InitializingBean { log.warn("Public URL is not valid: {}", StringUtils.defaultIfBlank(e.getMessage(), "")) } - log.info("--- Server config ---") log.info("Name: {}", getName()) log.info("Port: {}", getPort()) log.info("Public URL: {}", getPublicUrl()) diff --git a/src/main/groovy/io/kamax/mxisd/invitation/sender/EmailInviteSender.java b/src/main/groovy/io/kamax/mxisd/invitation/sender/EmailInviteSender.java index 854c783..8a67ac2 100644 --- a/src/main/groovy/io/kamax/mxisd/invitation/sender/EmailInviteSender.java +++ b/src/main/groovy/io/kamax/mxisd/invitation/sender/EmailInviteSender.java @@ -22,7 +22,7 @@ package io.kamax.mxisd.invitation.sender; import com.sun.mail.smtp.SMTPTransport; import io.kamax.matrix.ThreePidMedium; -import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.invite.sender.EmailSenderConfig; import io.kamax.mxisd.exception.ConfigurationException; import io.kamax.mxisd.invitation.IThreePidInviteReply; @@ -56,7 +56,7 @@ public class EmailInviteSender implements IInviteSender { private EmailSenderConfig cfg; @Autowired - private ServerConfig srvCfg; + private MatrixConfig mxCfg; @Autowired private ApplicationContext app; @@ -87,7 +87,7 @@ public class EmailInviteSender implements IInviteSender { } try { - String domainPretty = WordUtils.capitalizeFully(srvCfg.getName()); + String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain()); String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", ""); String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId()); String roomName = invite.getInvite().getProperties().getOrDefault("room_name", ""); @@ -97,7 +97,7 @@ public class EmailInviteSender implements IInviteSender { StringUtils.startsWith(cfg.getTemplate(), "classpath:") ? app.getResource(cfg.getTemplate()).getInputStream() : new FileInputStream(cfg.getTemplate()), StandardCharsets.UTF_8); - templateBody = templateBody.replace("%DOMAIN%", srvCfg.getName()); + templateBody = templateBody.replace("%DOMAIN%", mxCfg.getDomain()); templateBody = templateBody.replace("%DOMAIN_PRETTY%", domainPretty); templateBody = templateBody.replace("%FROM_EMAIL%", cfg.getEmail()); templateBody = templateBody.replace("%FROM_NAME%", cfg.getName()); diff --git a/src/main/groovy/io/kamax/mxisd/lookup/provider/DnsLookupProvider.groovy b/src/main/groovy/io/kamax/mxisd/lookup/provider/DnsLookupProvider.groovy index 40aec25..e63e030 100644 --- a/src/main/groovy/io/kamax/mxisd/lookup/provider/DnsLookupProvider.groovy +++ b/src/main/groovy/io/kamax/mxisd/lookup/provider/DnsLookupProvider.groovy @@ -20,7 +20,7 @@ package io.kamax.mxisd.lookup.provider -import io.kamax.mxisd.config.ServerConfig +import io.kamax.mxisd.config.MatrixConfig import io.kamax.mxisd.lookup.SingleLookupReply import io.kamax.mxisd.lookup.SingleLookupRequest import io.kamax.mxisd.lookup.ThreePidMapping @@ -44,7 +44,7 @@ class DnsLookupProvider implements IThreePidProvider { private Logger log = LoggerFactory.getLogger(DnsLookupProvider.class) @Autowired - private ServerConfig srvCfg + private MatrixConfig mxCfg @Autowired private IRemoteIdentityServerFetcher fetcher @@ -79,7 +79,7 @@ class DnsLookupProvider implements IThreePidProvider { // TODO use caching mechanism Optional findIdentityServerForDomain(String domain) { - if (StringUtils.equals(srvCfg.getName(), domain)) { + if (StringUtils.equals(mxCfg.getDomain(), domain)) { log.info("We are authoritative for {}, no remote lookup", domain) return Optional.empty() } diff --git a/src/main/groovy/io/kamax/mxisd/lookup/provider/LdapProvider.groovy b/src/main/groovy/io/kamax/mxisd/lookup/provider/LdapProvider.groovy index c2cc220..d8bb349 100644 --- a/src/main/groovy/io/kamax/mxisd/lookup/provider/LdapProvider.groovy +++ b/src/main/groovy/io/kamax/mxisd/lookup/provider/LdapProvider.groovy @@ -20,7 +20,7 @@ package io.kamax.mxisd.lookup.provider -import io.kamax.mxisd.config.ServerConfig +import io.kamax.mxisd.config.MatrixConfig import io.kamax.mxisd.config.ldap.LdapConfig import io.kamax.mxisd.lookup.SingleLookupReply import io.kamax.mxisd.lookup.SingleLookupRequest @@ -47,7 +47,7 @@ class LdapProvider implements IThreePidProvider { private Logger log = LoggerFactory.getLogger(LdapProvider.class) @Autowired - private ServerConfig srvCfg + private MatrixConfig mxCfg @Autowired private LdapConfig ldapCfg @@ -111,7 +111,7 @@ class LdapProvider implements IThreePidProvider { // TODO Should we turn this block into a map of functions? 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(mxCfg.getDomain()) } else if (StringUtils.equals(MATRIX_ID, uidType)) { matrixId.append(data) } else { diff --git a/src/main/groovy/io/kamax/mxisd/lookup/provider/SqlProvider.java b/src/main/groovy/io/kamax/mxisd/lookup/provider/SqlProvider.java index c7b7225..8529d65 100644 --- a/src/main/groovy/io/kamax/mxisd/lookup/provider/SqlProvider.java +++ b/src/main/groovy/io/kamax/mxisd/lookup/provider/SqlProvider.java @@ -21,7 +21,7 @@ package io.kamax.mxisd.lookup.provider; import io.kamax.matrix.MatrixID; -import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.sql.SqlProviderConfig; import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupRequest; @@ -43,7 +43,7 @@ public class SqlProvider implements IThreePidProvider { private Logger log = LoggerFactory.getLogger(SqlProvider.class); @Autowired - private ServerConfig srvCfg; + private MatrixConfig mxCfg; @Autowired private SqlProviderConfig cfg; @@ -82,7 +82,7 @@ public class SqlProvider implements IThreePidProvider { log.info("Found match: {}", uid); if (StringUtils.equals("uid", cfg.getIdentity().getType())) { log.info("Resolving as localpart"); - return Optional.of(new SingleLookupReply(request, new MatrixID(uid, srvCfg.getName()))); + return Optional.of(new SingleLookupReply(request, new MatrixID(uid, mxCfg.getDomain()))); } if (StringUtils.equals("mxid", cfg.getIdentity().getType())) { log.info("Resolving as MXID");