diff --git a/src/main/java/io/kamax/mxisd/as/AppSvcManager.java b/src/main/java/io/kamax/mxisd/as/AppSvcManager.java index 403beef..79c7a01 100644 --- a/src/main/java/io/kamax/mxisd/as/AppSvcManager.java +++ b/src/main/java/io/kamax/mxisd/as/AppSvcManager.java @@ -35,11 +35,18 @@ import io.kamax.mxisd.profile.ProfileManager; import io.kamax.mxisd.storage.IStorage; import io.kamax.mxisd.storage.ormlite.dao.ASTransactionDao; import io.kamax.mxisd.util.GsonParser; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.introspector.BeanAccess; +import org.yaml.snakeyaml.representer.Representer; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -65,6 +72,26 @@ public class AppSvcManager { transactionsInProgress = new ConcurrentHashMap<>(); processors.put("m.room.member", new MembershipProcessor(cfg.getMatrix(), profiler, notif, synapse)); + + processConfig(); + } + + private void processConfig() { + String synapseRegFile = cfg.getListener().getSynapse().getRegistrationFile(); + if (StringUtils.isNotBlank(synapseRegFile)) { + SynapseRegistrationYaml syncCfg = SynapseRegistrationYaml.parse(cfg.getListener()); + + Representer rep = new Representer(); + rep.getPropertyUtils().setBeanAccess(BeanAccess.FIELD); + Yaml yaml = new Yaml(rep); + String synCfgRaw = yaml.dump(syncCfg); + + try { + IOUtils.write(synCfgRaw, new FileOutputStream(synapseRegFile), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Unable to write synapse appservice registration file", e); + } + } } public AppSvcManager withToken(String token) { diff --git a/src/main/java/io/kamax/mxisd/as/MembershipProcessor.java b/src/main/java/io/kamax/mxisd/as/MembershipProcessor.java index c0d8643..2e9b3cf 100644 --- a/src/main/java/io/kamax/mxisd/as/MembershipProcessor.java +++ b/src/main/java/io/kamax/mxisd/as/MembershipProcessor.java @@ -26,7 +26,6 @@ import io.kamax.matrix.ThreePidMedium; import io.kamax.matrix._MatrixID; import io.kamax.matrix._ThreePid; import io.kamax.matrix.event.EventKey; -import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.backend.sql.synapse.Synapse; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.notification.NotificationManager; @@ -63,7 +62,7 @@ public class MembershipProcessor implements EventTypeProcessor { return ev; }); - if (!StringUtils.equals("invite", GsonUtil.getStringOrNull(content, "membership"))) { + if (!StringUtils.equals("invite", EventKey.Membership.getStringOrNull(content))) { log.debug("This is not an invite event, skipping"); return; } diff --git a/src/main/java/io/kamax/mxisd/as/SynapseRegistrationYaml.java b/src/main/java/io/kamax/mxisd/as/SynapseRegistrationYaml.java new file mode 100644 index 0000000..370fedb --- /dev/null +++ b/src/main/java/io/kamax/mxisd/as/SynapseRegistrationYaml.java @@ -0,0 +1,168 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2019 Kamax Sarl + * + * https://www.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.as; + +import io.kamax.mxisd.config.ListenerConfig; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class SynapseRegistrationYaml { + + public static SynapseRegistrationYaml parse(ListenerConfig cfg) { + SynapseRegistrationYaml yaml = new SynapseRegistrationYaml(); + + yaml.setId("appservice-mxisd"); + yaml.setUrl(cfg.getUrl()); + yaml.setAsToken(cfg.getToken().getAs()); + yaml.setHsToken(cfg.getToken().getHs()); + yaml.setSenderLocalpart(cfg.getLocalpart()); + cfg.getUsers().forEach(template -> { + Namespace ns = new Namespace(); + ns.setRegex(template.getTemplate()); + ns.setExclusive(true); + yaml.getNamespaces().getUsers().add(ns); + }); + + return yaml; + } + + public static class Namespace { + + private String regex; + private boolean exclusive; + + public String getRegex() { + return regex; + } + + public void setRegex(String regex) { + this.regex = regex; + } + + public boolean isExclusive() { + return exclusive; + } + + public void setExclusive(boolean exclusive) { + this.exclusive = exclusive; + } + + } + + public static class Namespaces { + + private List users = new ArrayList<>(); + private List aliases = new ArrayList<>(); + private List rooms = new ArrayList<>(); + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public List getAliases() { + return aliases; + } + + public void setAliases(List aliases) { + this.aliases = aliases; + } + + public List getRooms() { + return rooms; + } + + public void setRooms(List rooms) { + this.rooms = rooms; + } + + } + + private String id; + private String url; + private String as_token; + private String hs_token; + private String sender_localpart; + private Namespaces namespaces = new Namespaces(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setUrl(URL url) { + if (Objects.isNull(url)) { + this.url = null; + } else { + this.url = url.toString(); + } + } + + public String getAsToken() { + return as_token; + } + + public void setAsToken(String as_token) { + this.as_token = as_token; + } + + public String getHsToken() { + return hs_token; + } + + public void setHsToken(String hs_token) { + this.hs_token = hs_token; + } + + public String getSenderLocalpart() { + return sender_localpart; + } + + public void setSenderLocalpart(String sender_localpart) { + this.sender_localpart = sender_localpart; + } + + public Namespaces getNamespaces() { + return namespaces; + } + + public void setNamespaces(Namespaces namespaces) { + this.namespaces = namespaces; + } + +} diff --git a/src/main/java/io/kamax/mxisd/config/ListenerConfig.java b/src/main/java/io/kamax/mxisd/config/ListenerConfig.java index 9a468b2..14d9937 100644 --- a/src/main/java/io/kamax/mxisd/config/ListenerConfig.java +++ b/src/main/java/io/kamax/mxisd/config/ListenerConfig.java @@ -25,9 +25,48 @@ import org.apache.commons.lang.StringUtils; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; public class ListenerConfig { + public static class Synpase { + + private String registrationFile; + + public String getRegistrationFile() { + return registrationFile; + } + + public void setRegistrationFile(String registrationFile) { + this.registrationFile = registrationFile; + } + + } + + public static class UserTemplate { + + private String type = "regex"; + private String template; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + + } + public static class Token { private String as; @@ -51,10 +90,22 @@ public class ListenerConfig { } - private transient URL csUrl; + private String id = "appservice-mxisd"; private String url; - private String localpart; + private String localpart = "mxisd"; private Token token = new Token(); + private List users = new ArrayList<>(); + private Synpase synapse = new Synpase(); + + private transient URL csUrl; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } public URL getUrl() { return csUrl; @@ -80,6 +131,22 @@ public class ListenerConfig { this.token = token; } + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public Synpase getSynapse() { + return synapse; + } + + public void setSynapse(Synpase synapse) { + this.synapse = synapse; + } + public void build() { try { if (StringUtils.isBlank(url)) { @@ -88,6 +155,10 @@ public class ListenerConfig { csUrl = new URL(url); + if (org.apache.commons.lang3.StringUtils.isBlank(getId())) { + throw new IllegalArgumentException("Matrix Listener ID is not set"); + } + if (StringUtils.isBlank(getLocalpart())) { throw new IllegalArgumentException("localpart for matrix listener is not set"); }