Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f13748abeb | ||
|
7208c7e456 | ||
|
8857f636d6 | ||
|
d9fc41e8c7 | ||
|
da08e0b4ad | ||
|
11fc8f08b0 | ||
|
af4d734105 | ||
|
0f4f5ac81b | ||
|
8c4ddd2e65 | ||
|
cb8049b54a | ||
|
99b7d9f27d | ||
|
ded5e3db5e | ||
|
b892d19023 | ||
|
026a2e82d9 | ||
|
b881f73798 | ||
|
99d793b5ed | ||
|
cb02f62b9d | ||
|
bd9161ec9b | ||
|
544cab816c | ||
|
cdb56aec1f | ||
|
407138e972 | ||
|
3eee4eaccf | ||
|
b3aefbed77 | ||
|
29017fbe1e | ||
|
843fa04f19 | ||
|
f7d1a300f1 | ||
|
f16eb264be | ||
|
f29014be1f | ||
|
20a4d8dd91 | ||
|
0c0feab0c0 | ||
|
dd313881db | ||
|
feb37112b2 | ||
|
1ab8a27fda | ||
|
deafc420a5 | ||
|
fce15f0e29 | ||
|
5b5893f407 | ||
|
f55d5fbc80 | ||
|
b613415dc4 | ||
|
0549d23d21 | ||
|
b493ccd479 | ||
|
03e72ba155 | ||
|
32a3444a9e | ||
|
78a25c21ba | ||
|
ef80f4aa30 | ||
|
1e413af019 |
101
README.md
101
README.md
@@ -1,10 +1,10 @@
|
|||||||
mxisd - Federated Matrix Identity Server Daemon
|
mxisd - Federated Matrix Identity Server
|
||||||
-----
|
----------------------------------------
|
||||||

|

|
||||||
|
|
||||||
- [Overview](#overview)
|
- [Overview](#overview)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Why use mxisd](#why-use-mxisd)
|
- [Use cases](#use-cases)
|
||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
- [Support](#support)
|
- [Support](#support)
|
||||||
- [Contribute](#contribute)
|
- [Contribute](#contribute)
|
||||||
@@ -13,80 +13,77 @@ mxisd - Federated Matrix Identity Server Daemon
|
|||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
mxisd is a Federated Matrix Identity server for self-hosted Matrix infrastructures with [enhanced features](#features).
|
mxisd is a Federated Matrix Identity server for self-hosted Matrix infrastructures with [enhanced features](#features).
|
||||||
|
As an enhanced Identity service, it implements the [Matrix Identity service API](https://kamax.io/matrix/api/identity_service/unstable.html)
|
||||||
|
and several [extra features](#features) that greatly enhance user experience within Matrix.
|
||||||
|
It is the one stop shop for anything regarding Authentication, Directory and Identity management in Matrix built in a
|
||||||
|
single coherent product.
|
||||||
|
|
||||||
It is specifically designed to connect to an Identity store (AD/Samba/LDAP, SQL Database, Web services/application, ...)
|
mxisd is specifically designed to connect to an existing on-premise Identity store (AD/Samba/LDAP, SQL Database,
|
||||||
and ease the integration of the Matrix ecosystem with an existing infrastructure, or to build a new one using lasting
|
Web services/app, etc.) and ease the integration of a Matrix infrastructure within an existing one.
|
||||||
tools.
|
|
||||||
|
|
||||||
The core principle of mxisd is to map between Matrix IDs and 3PIDs (Third-party Identifiers) for the Homeserver and its
|
The core principle of mxisd is to map between Matrix IDs and 3PIDs (Third-Party IDentifiers) for the Homeserver and its
|
||||||
users. 3PIDs can be anything that identify a user, like:
|
users. 3PIDs can be anything that uniquely and globally identify a user, like:
|
||||||
- Full name
|
|
||||||
- Email address
|
- Email address
|
||||||
- Phone number
|
- Phone number
|
||||||
- Employee number
|
|
||||||
- Skype/Live ID
|
- Skype/Live ID
|
||||||
- Twitter handle
|
- Twitter handle
|
||||||
- Facebook ID
|
- Facebook ID
|
||||||
- ...
|
|
||||||
|
|
||||||
mxisd is an enhanced Identity service, which implements the
|
If you are unfamiliar with the Identity vocabulary and concepts in Matrix, **please read this [introduction](docs/concepts.md)**.
|
||||||
[Matrix Identity service API](https://matrix.org/docs/spec/identity_service/unstable.html) but also several
|
|
||||||
[other features](#features) that greatly enhance user experience within Matrix.
|
|
||||||
|
|
||||||
mxisd is the one stop shop for anything regarding Authentication, Directory and Identity management in Matrix built as a
|
|
||||||
single coherent product.
|
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
As a [regular Matrix Identity service](docs/features/identity.md):
|
[Identity](docs/features/identity.md): As a [regular Matrix Identity service](https://kamax.io/matrix/api/identity_service/unstable.html#general-principles):
|
||||||
- Search for people by 3PID using its own Identity stores (LDAP, SQL, etc.)
|
- Search for people by 3PID using its own Identity stores
|
||||||
- Invite people to rooms by 3PID using its own Identity stores, with [notifications](docs/README.md)
|
([Spec](https://kamax.io/matrix/api/identity_service/unstable.html#association-lookup))
|
||||||
to the invitee (Email, SMS, etc.)
|
- Invite people to rooms by 3PID using its own Identity stores, with notifications to the invitee (Email, SMS, etc.)
|
||||||
|
([Spec](https://kamax.io/matrix/api/identity_service/unstable.html#post-matrix-identity-api-v1-store-invite))
|
||||||
- Allow users to add 3PIDs to their settings/profile
|
- Allow users to add 3PIDs to their settings/profile
|
||||||
|
([Spec](https://kamax.io/matrix/api/identity_service/unstable.html#establishing-associations))
|
||||||
|
- Register accounts on your Homeserver with 3PIDs
|
||||||
|
([Spec](https://kamax.io/matrix/api/identity_service/unstable.html#establishing-associations))
|
||||||
|
|
||||||
As an enhanced Identity service:
|
As an enhanced Identity service:
|
||||||
- Use a recursive lookup mechanism when searching and inviting people by 3PID, allowing to fetch data from:
|
- [Federation](docs/features/federation.md): Use a recursive lookup mechanism when searching and inviting people by 3PID,
|
||||||
- Own Identity store
|
allowing to fetch data from:
|
||||||
|
- Own Identity store(s)
|
||||||
- Federated Identity servers, if applicable to the 3PID
|
- Federated Identity servers, if applicable to the 3PID
|
||||||
- Arbitrary Identity servers
|
- Arbitrary Identity servers
|
||||||
- Central Matrix Identity servers
|
- Central Matrix Identity servers
|
||||||
- [Extensive control of where 3PIDs are transmited](docs/sessions/3pid.md), so they are not leaked publicly by users
|
- [Session Control](docs/threepids/session/session.md): Extensive control of where 3PIDs are transmitted so they are not
|
||||||
- [Authentication support](docs/features/authentication.md) for [synapse](https://github.com/matrix-org/synapse) via the
|
leaked publicly by users
|
||||||
[REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth)
|
- [Authentication](docs/features/authentication.md): Use your Identity stores to perform authentication in [synapse](https://github.com/matrix-org/synapse)
|
||||||
- [Directory integration](docs/features/directory-users.md) which allows you to search for users within your
|
via the [REST password provider](https://github.com/kamax-io/matrix-synapse-rest-auth)
|
||||||
organisation, even without prior Matrix contact
|
- [Directory search](docs/features/directory.md) which allows you to search for users within your organisation,
|
||||||
- [Auto-fill of user profile](docs/features/authentication.md) (Display name, 3PIDs) via the
|
even without prior contact within Matrix using arbitrary search terms
|
||||||
[REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth)
|
- [Auto-fill of user profile](docs/features/authentication.md#profile-auto-fill) (Display name, 3PIDs)
|
||||||
|
- [Bridge Integration](docs/features/bridge-integration.md): Automatically bridge users without a published Matrix ID
|
||||||
|
|
||||||
# Why use mxisd
|
# Use cases
|
||||||
- Use your existing Identity store, do not duplicate information
|
- Use your existing Identity stores, do not duplicate your users information
|
||||||
- Auto-fill user profiles with relevant information
|
- Auto-fill user profiles with relevant information
|
||||||
- As an organisation, stay in control of 3PIDs so they are not published to the central Matrix.org servers where they
|
- As an organisation, stay in control of your data so it is not published to other servers by default where they
|
||||||
currently **cannot be removed**
|
currently **cannot be removed**
|
||||||
- Users can directly find each other using whatever attribute is relevant within your Identity store
|
- Users can directly find each other using whatever attribute is relevant within your Identity store
|
||||||
- Federate your Identity lookups so you can discover others and/or others can discover you, all with extensive ACLs
|
- Federate your Identity server so you can discover others and/or others can discover you
|
||||||
|
|
||||||
# Getting started
|
# Getting started
|
||||||
See the [dedicated document](docs/getting-started.md)
|
See the [dedicated document](docs/getting-started.md)
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
## Community
|
## Community
|
||||||
If you need help, want to report a bug or just say hi, you can reach us on Matrix at
|
Over Matrix: [#mxisd:kamax.io](https://matrix.to/#/#mxisd:kamax.io) ([Preview](https://view.matrix.org/room/!NPRUEisLjcaMtHIzDr:kamax.io/))
|
||||||
[#mxisd:kamax.io](https://matrix.to/#/#mxisd:kamax.io) or
|
|
||||||
[directly peek anonymously](https://view.matrix.org/room/!NPRUEisLjcaMtHIzDr:kamax.io/).
|
|
||||||
For more high-level discussion about the Identity Server architecture/API, go to
|
|
||||||
[#matrix-identity:matrix.org](https://matrix.to/#/#matrix-identity:matrix.org)
|
|
||||||
|
|
||||||
## Professional
|
For more high-level discussion about the Identity Server architecture/API, go to [#matrix-identity:kamax.io](https://matrix.to/#/#matrix-identity:kamax.io)
|
||||||
|
|
||||||
|
## Commercial
|
||||||
If you would prefer professional support/custom development for mxisd and/or for Matrix in general, including other open
|
If you would prefer professional support/custom development for mxisd and/or for Matrix in general, including other open
|
||||||
source technologies/products, please visit [our website](https://www.kamax.io/) to get in touch with us and get a quote.
|
source technologies/products:
|
||||||
|
- Visit our [website](https://www.kamax.io/) to get in touch with us and get a quote.
|
||||||
We offer affordable monthly/yearly support plans for mxisd, synapse or your full Matrix infrastructure.
|
- Come in our general Matrix room: [#kamax-matrix:kamax.io](https://matrix.to/#/#kamax-matrix:kamax.io)
|
||||||
|
|
||||||
# Contribute
|
|
||||||
First and foremost, the best way to contribute is to use mxisd and tell us about it!
|
|
||||||
We would love to hear about your experience and get your feedback on how to make it an awesome product.
|
|
||||||
|
|
||||||
|
# Contribute
|
||||||
You can contribute as a community member by:
|
You can contribute as a community member by:
|
||||||
|
- Giving us feedback about your usage of mxisd, even if it seems unimportant or if all is working well!
|
||||||
- Opening issues for any weird behaviour or bug. mxisd should feel natural, let us know if it does not!
|
- Opening issues for any weird behaviour or bug. mxisd should feel natural, let us know if it does not!
|
||||||
- Helping us improve the documentation: tell us what is good or not good (in an issue or in Matrix), or make a PR with
|
- Helping us improve the documentation: tell us what is good or not good (in an issue or in Matrix), or make a PR with
|
||||||
changes you feel improve the doc.
|
changes you feel improve the doc.
|
||||||
@@ -95,7 +92,7 @@ changes you feel improve the doc.
|
|||||||
be used for the fixed costs and developer time of mxisd.
|
be used for the fixed costs and developer time of mxisd.
|
||||||
|
|
||||||
You can contribute as an organisation/corporation by:
|
You can contribute as an organisation/corporation by:
|
||||||
- Get a [support contract](#support-professional). This is the best way you can help us as it ensures mxisd is
|
- Get a [support contract](#commercial). This is the best way you can help us as it ensures mxisd is
|
||||||
maintained regularly and you get direct access to the support team.
|
maintained regularly and you get direct access to the support team.
|
||||||
- Sponsoring new features or bug fixes. [Get in touch](#contact) so we can discuss it further.
|
- Sponsoring new features or bug fixes. [Get in touch](#contact) so we can discuss it further.
|
||||||
|
|
||||||
@@ -104,5 +101,5 @@ See the [dedicated document](docs/faq.md)
|
|||||||
|
|
||||||
# Contact
|
# Contact
|
||||||
Get in touch via:
|
Get in touch via:
|
||||||
- Matrix at [#mxisd:kamax.io](https://matrix.to/#/#mxisd:kamax.io)
|
- Matrix: [#mxisd:kamax.io](https://matrix.to/#/#mxisd:kamax.io)
|
||||||
- Email, see our website: [Kamax.io](https://www.kamax.io)
|
- Email: see our website: [Kamax.io](https://www.kamax.io)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Sample configuration file explaining the minimum required keys to be set to run mxisd
|
# Sample configuration file explaining the minimum required keys to be set to run mxisd
|
||||||
#
|
#
|
||||||
# For a complete list of options, see https://github.com/kamax-io/mxisd
|
# For a complete list of options, see https://github.com/kamax-matrix/mxisd
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Matrix config items #
|
# Matrix config items #
|
||||||
@@ -47,30 +47,45 @@ 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-matrix/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-matrix/mxisd/blob/master/docs/stores/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-matrix/mxisd/blob/master/docs/stores/sql.md
|
||||||
|
|
||||||
|
|
||||||
################
|
################
|
||||||
# REST Backend #
|
# REST Backend #
|
||||||
################
|
################
|
||||||
# If you would like to integrate with an existing web service/webapp,
|
# If you would like to integrate with an existing web service/webapp,
|
||||||
# see https://github.com/kamax-io/mxisd/blob/master/docs/backends/rest.md
|
# see https://github.com/kamax-matrix/mxisd/blob/master/docs/stores/rest.md
|
||||||
|
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# Notifications for invites/addition to profile #
|
# Notifications for invites/addition to profile #
|
||||||
#################################################
|
#################################################
|
||||||
# If you would like to change the content,
|
# If you would like to change the content,
|
||||||
# see https://github.com/kamax-io/mxisd/blob/master/docs/threepids/notifications/template-generator.md
|
# see https://github.com/kamax-matrix/mxisd/blob/master/docs/threepids/notification/template-generator.md
|
||||||
#
|
#
|
||||||
#### E-mail invite sender
|
#### E-mail invite sender
|
||||||
#
|
#
|
||||||
|
37
build.gradle
37
build.gradle
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -41,17 +41,25 @@ def debBuildDataPath = "${debBuildBasePath}${debDataPath}"
|
|||||||
def debBuildSystemdPath = "${debBuildBasePath}${debSystemdPath}"
|
def debBuildSystemdPath = "${debBuildBasePath}${debSystemdPath}"
|
||||||
|
|
||||||
def dockerImageName = "kamax/mxisd"
|
def dockerImageName = "kamax/mxisd"
|
||||||
def dockerImageTag = "${dockerImageName}:${gitVersion()}"
|
def dockerImageTag = "${dockerImageName}:${mxisdVersion()}"
|
||||||
|
|
||||||
|
String mxisdVersion() {
|
||||||
|
def versionPattern = Pattern.compile("v(\\d+\\.)?(\\d+\\.)?(\\d+)(-.*)?")
|
||||||
|
|
||||||
|
String version = System.getenv('MXISD_BUILD_VERSION')
|
||||||
|
if (version == null || version.size() == 0) {
|
||||||
|
version = gitVersion()
|
||||||
|
}
|
||||||
|
return versionPattern.matcher(version).matches() ? version.substring(1) : version
|
||||||
|
}
|
||||||
|
|
||||||
String gitVersion() {
|
String gitVersion() {
|
||||||
def versionPattern = Pattern.compile("v(\\d+\\.)?(\\d+\\.)?(\\d+)(-.*)?")
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
||||||
exec {
|
exec {
|
||||||
commandLine = ['git', 'describe', '--tags', '--always', '--dirty']
|
commandLine = ['git', 'describe', '--tags', '--always', '--dirty']
|
||||||
standardOutput = out
|
standardOutput = out
|
||||||
}
|
}
|
||||||
def v = out.toString().replace(System.lineSeparator(), '')
|
return out.toString().replace(System.lineSeparator(), '');
|
||||||
return versionPattern.matcher(v).matches() ? v.substring(1) : v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
@@ -65,8 +73,9 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url "https://kamax.io/maven/releases/" }
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven { url "https://kamax.io/maven/releases/" }
|
||||||
|
maven { url "https://kamax.io/maven/snapshots/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -80,7 +89,7 @@ dependencies {
|
|||||||
compile "org.springframework.boot:spring-boot-starter-thymeleaf:1.5.10.RELEASE"
|
compile "org.springframework.boot:spring-boot-starter-thymeleaf:1.5.10.RELEASE"
|
||||||
|
|
||||||
// Matrix Java SDK
|
// Matrix Java SDK
|
||||||
compile 'io.kamax:matrix-java-sdk:0.0.8'
|
compile 'io.kamax:matrix-java-sdk:0.0.14-8-g0e57ec6'
|
||||||
|
|
||||||
// ed25519 handling
|
// ed25519 handling
|
||||||
compile 'net.i2p.crypto:eddsa:0.1.0'
|
compile 'net.i2p.crypto:eddsa:0.1.0'
|
||||||
@@ -94,15 +103,12 @@ dependencies {
|
|||||||
// HTTP connections
|
// HTTP connections
|
||||||
compile 'org.apache.httpcomponents:httpclient:4.5.3'
|
compile 'org.apache.httpcomponents:httpclient:4.5.3'
|
||||||
|
|
||||||
// JSON
|
|
||||||
compile 'com.google.code.gson:gson:2.8.1'
|
|
||||||
|
|
||||||
// Phone numbers validation
|
// Phone numbers validation
|
||||||
compile 'com.googlecode.libphonenumber:libphonenumber:8.7.1'
|
compile 'com.googlecode.libphonenumber:libphonenumber:8.7.1'
|
||||||
|
|
||||||
// E-mail sending
|
// E-mail sending
|
||||||
compile 'com.sun.mail:javax.mail:1.5.6'
|
compile 'com.sun.mail:javax.mail:1.6.2'
|
||||||
compile 'javax.mail:javax.mail-api:1.5.6'
|
compile 'javax.mail:javax.mail-api:1.6.2'
|
||||||
|
|
||||||
// Google Firebase Authentication backend
|
// Google Firebase Authentication backend
|
||||||
compile 'com.google.firebase:firebase-admin:5.3.0'
|
compile 'com.google.firebase:firebase-admin:5.3.0'
|
||||||
@@ -128,6 +134,9 @@ dependencies {
|
|||||||
// SendGrid SDK to send emails from GCE
|
// SendGrid SDK to send emails from GCE
|
||||||
compile 'com.sendgrid:sendgrid-java:2.2.2'
|
compile 'com.sendgrid:sendgrid-java:2.2.2'
|
||||||
|
|
||||||
|
// ZT-Exec for exec identity store
|
||||||
|
compile 'org.zeroturnaround:zt-exec:1.10'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'com.github.tomakehurst:wiremock:2.8.0'
|
testCompile 'com.github.tomakehurst:wiremock:2.8.0'
|
||||||
}
|
}
|
||||||
@@ -153,7 +162,7 @@ processResources {
|
|||||||
|
|
||||||
task buildDeb(dependsOn: build) {
|
task buildDeb(dependsOn: build) {
|
||||||
doLast {
|
doLast {
|
||||||
def v = gitVersion()
|
def v = mxisdVersion()
|
||||||
println "Version for package: ${v}"
|
println "Version for package: ${v}"
|
||||||
mkdir distDir
|
mkdir distDir
|
||||||
mkdir debBuildBasePath
|
mkdir debBuildBasePath
|
||||||
|
@@ -1,26 +1,25 @@
|
|||||||
# Table of Contents
|
# Table of Contents
|
||||||
|
- [Identity Concepts in Matrix](concepts.md)
|
||||||
|
- [Getting Started](getting-started.md)
|
||||||
|
- [Build from sources](build.md) (Optional)
|
||||||
- Installation
|
- Installation
|
||||||
- [Debian package](install/debian.md)
|
- [Debian package](install/debian.md)
|
||||||
|
- [ArchLinux](install/archlinux.md)
|
||||||
- [Docker](install/docker.md)
|
- [Docker](install/docker.md)
|
||||||
- [Build from source](build.md)
|
- [From source](install/source.md)
|
||||||
- [Architecture overview](architecture.md)
|
- [Architecture overview](architecture.md)
|
||||||
- [Configuration](configure.md)
|
- [Configuration](configure.md)
|
||||||
- Features
|
- Features
|
||||||
- [Matrix Identity Service](features/identity.md)
|
- [Authentication](features/authentication.md)
|
||||||
- [Homeserver Authentication](features/authentication.md)
|
- [Directory search](features/directory.md)
|
||||||
- [Directory seach](features/directory-users.md)
|
- [Identity](features/identity.md)
|
||||||
- [Identity server Federation](features/federation.md)
|
- [Federation](features/federation.md)
|
||||||
- [Bridge integration](features/bridge-integration.md)
|
- [Bridge integration](features/bridge-integration.md)
|
||||||
- Backends
|
- [Identity Stores](stores/README.md)
|
||||||
- [LDAP](backends/ldap.md)
|
|
||||||
- [SQL](backends/sql.md)
|
|
||||||
- [REST](backends/rest.md)
|
|
||||||
- [Google Firebase](backends/firebase.md)
|
|
||||||
- [Wordpress](backends/wordpress.md)
|
|
||||||
- Notifications
|
- Notifications
|
||||||
- Handlers
|
- Handlers
|
||||||
- [Basic](threepids/notifications/basic-handler.md)
|
- [Basic](threepids/notification/basic-handler.md)
|
||||||
- [SendGrid](threepids/notifications/sendgrid-handler.md)
|
- [SendGrid](threepids/notification/sendgrid-handler.md)
|
||||||
- [Sessions](sessions/3pid.md)
|
- [Sessions](threepids/session/session.md)
|
||||||
- [Views](sessions/3pid-views.md)
|
- [Views](threepids/session/session-views.md)
|
||||||
|
- [FAQ](faq.md)
|
@@ -1,6 +1,6 @@
|
|||||||
# Architecture
|
# Architecture
|
||||||
## Overview
|
## Overview
|
||||||
### Basic setup without integration or incoming federation
|
### Basic setup with default settings
|
||||||
```
|
```
|
||||||
Client
|
Client
|
||||||
|
|
|
|
||||||
@@ -14,17 +14,14 @@ TCP 443
|
|||||||
+--|------------------+ +---|-----------------------+
|
+--|------------------+ +---|-----------------------+
|
||||||
| |
|
| |
|
||||||
+<---------------------------------<+
|
+<---------------------------------<+
|
||||||
| Backends
|
|
|
||||||
| +-------------------+ +------+ +--------+
|
| +-------------------+
|
||||||
TCP 8090 +-> | mxisd | +-----> | LDAP | -> | SQL DB |
|
TCP 8090 +-> | mxisd |
|
||||||
| | | +------+ +--------+ ....
|
| |
|
||||||
| - Profile's 3PIDs >----+ |
|
| - Profile's 3PIDs |
|
||||||
| - 3PID Invites | | |
|
| - 3PID Invites |
|
||||||
+-|-----------------+ +>----+
|
+-|-----------------+
|
||||||
| | | +--------------------------+
|
|
|
||||||
| | | | Central Identity service |
|
|
||||||
+>-------------------->+ +-----> | Matrix.org / Vector.im |
|
|
||||||
| TCP 443 +--------------------------+
|
|
||||||
TCP 443
|
TCP 443
|
||||||
| +------------------------+
|
| +------------------------+
|
||||||
| | Remote Federated |
|
| | Remote Federated |
|
||||||
@@ -37,7 +34,7 @@ TCP 443
|
|||||||
See the [dedicated document](features/authentication.md).
|
See the [dedicated document](features/authentication.md).
|
||||||
|
|
||||||
### With Directory
|
### With Directory
|
||||||
See the [dedicated document](features/directory-users.md).
|
See the [dedicated document](features/directory.md).
|
||||||
|
|
||||||
### With Federation
|
### With Federation
|
||||||
See the [dedicated document](features/federation.md).
|
See the [dedicated document](features/federation.md).
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
# Identity Stores (Backends)
|
|
||||||
- [Samba / Active Directory / LDAP](ldap.md)
|
|
||||||
- [SQL Databases](sql.md)
|
|
||||||
- [Website / Web service / Web app](rest.md)
|
|
||||||
- [Google Firebase](firebase.md)
|
|
||||||
- [Wordpress](wordpress.md)
|
|
@@ -1,19 +0,0 @@
|
|||||||
# Google Firebase
|
|
||||||
https://firebase.google.com/
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
This backend requires a suitable Matrix client capable of performing Firebase authentication and passing the following
|
|
||||||
information:
|
|
||||||
- Firebase User ID as Matrix username
|
|
||||||
- Firebase token as Matrix password
|
|
||||||
|
|
||||||
If your client is Riot, you will need a custom version.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
To be completed. For now, see default structure and values:
|
|
||||||
```
|
|
||||||
firebase:
|
|
||||||
enabled: false
|
|
||||||
credentials: '/path/to/firebase/credentials.json'
|
|
||||||
database: 'https://my-project.firebaseio.com/'
|
|
||||||
```
|
|
@@ -1,140 +0,0 @@
|
|||||||
# LDAP (Samba / Active Directory / OpenLDAP)
|
|
||||||
## Getting started
|
|
||||||
To use your LDAP backend, add the bare minimum configuration in mxisd config file:
|
|
||||||
```
|
|
||||||
ldap.enabled: true
|
|
||||||
ldap.connection.host: 'ldapHostnameOrIp'
|
|
||||||
ldap.connection.bindDn: 'CN=My Mxisd User,OU=Users,DC=example,DC=org'
|
|
||||||
ldap.connection.bindPassword: 'TheUserPassword'
|
|
||||||
ldap.connection.baseDn: 'OU=Users,DC=example,DC=org'
|
|
||||||
```
|
|
||||||
These are standard LDAP connection configuration. mxisd will try to connect on port default port 389 without encryption.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
If you would like to use a TLS/SSL connection, use the following configuration options (STARTLS not supported):
|
|
||||||
```
|
|
||||||
ldap.connection.tls: true
|
|
||||||
ldap.connection.port: 12345
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You can also set a default global filter on any LDAP queries:
|
|
||||||
```
|
|
||||||
ldap.filter: '(memberOf=CN=My Matrix Users,OU=Groups,DC=example,DC=org)'
|
|
||||||
```
|
|
||||||
This example would only return users part of the group called `My Matrix Users`.
|
|
||||||
This can be overwritten or append in each specific flow describe below.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
LDAP features are based on mapping LDAP attributes to Matrix concepts, like a Matrix ID, its localpart, the user display
|
|
||||||
name, their email(s) and/or phone number(s).
|
|
||||||
|
|
||||||
Default attributes are well suited for Active Directory/Samba. In case you are using a native LDAP backend, you will
|
|
||||||
most certainly configure those mappings.
|
|
||||||
|
|
||||||
The following example would set the `uid` attribute as localpart and the Matrix display name to `cn`
|
|
||||||
```
|
|
||||||
ldap.attribute.uid.type: 'uid'
|
|
||||||
ldap.attribute.uid.value: 'uid'
|
|
||||||
ldap.attribute.name: 'cn'
|
|
||||||
```
|
|
||||||
|
|
||||||
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:
|
|
||||||
```
|
|
||||||
ldap.attribute.threepid.email:
|
|
||||||
- 'mail'
|
|
||||||
- 'otherMailAttribute'
|
|
||||||
|
|
||||||
ldap.attribute.threepid.msisdn:
|
|
||||||
- 'phone'
|
|
||||||
- 'otherPhoneAttribute'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Identity
|
|
||||||
Identity features (related to 3PID invites or searches) are enabled and configured using default values and no specific
|
|
||||||
configuration item is needed to get started.
|
|
||||||
|
|
||||||
If you would like to overwrite some global configuration relative to filter and/or attributes, see the Identity section
|
|
||||||
of the Configuration below.
|
|
||||||
|
|
||||||
## Authentication
|
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
|
||||||
No further configuration is needed to enable directory with LDAP once globally enabled and configured.
|
|
||||||
|
|
||||||
If you would like to use extra attributes in search that are not 3PIDs, like nicknames, group names, employee number:
|
|
||||||
```
|
|
||||||
ldap.directory.attribute.other:
|
|
||||||
- 'myNicknameAttribute'
|
|
||||||
- 'memberOf'
|
|
||||||
- 'employeeNumberAttribute'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
Please read the [Configuration](../configure.md) explanatory note if you are not familiar with the terms used below.
|
|
||||||
|
|
||||||
### General
|
|
||||||
Base path: `ldap`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|-----------|-------------------------------------------------------------------------------------------|
|
|
||||||
| `enabled` | Globaly enable/disable the LDAP backend |
|
|
||||||
| `filter` | Global filter to apply on all LDAP queries. Can be overwritten in each applicable section |
|
|
||||||
|
|
||||||
### Connection
|
|
||||||
Base path: `ldap.connection`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|----------------|------------------------------------------------------|
|
|
||||||
| `host` | Host to connect to |
|
|
||||||
| `port` | Port to use |
|
|
||||||
| `tls` | boolean to use TLS or not (STARTLS is not supported) |
|
|
||||||
| `bindDn` | Bind DN for authentication |
|
|
||||||
| `bindPassword` | Bind password |
|
|
||||||
| `baseDn` | Base DN for queries |
|
|
||||||
|
|
||||||
### Attributes
|
|
||||||
Base path: `ldap.attribute`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|-------------|------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| `uid.type` | Indicate how to process the User ID (UID) attribute: |
|
|
||||||
| | - `uid` will consider the value as the [Localpart](https://matrix.org/docs/spec/intro.html#user-identifiers) |
|
|
||||||
| | - `mxid` will consider the value as a complete [Matrix ID](https://matrix.org/docs/spec/intro.html#user-identifiers) |
|
|
||||||
| `uid.value` | Attribute name refering to the User ID. This is typically `userPrincipalName` on AD/Samba setups and `uid` in LDAP |
|
|
||||||
| `name` | Attribute name that contains the [Display Name](https://matrix.org/docs/spec/intro.html#profiles) of the user |
|
|
||||||
| `threepid` | Namespace where each key is a 3PID type and contains a list of attributes |
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
Base path: `ldap.auth`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|----------|--------------------------------------------------------------------------------------------------|
|
|
||||||
| `filter` | Specific user filter applied during authentication. Global filter is used if empty/blank/not set |
|
|
||||||
|
|
||||||
### Directory
|
|
||||||
Base path: `ldap.directory`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|-------------------|---------------------------------------------------------------------|
|
|
||||||
| `attribute.other` | Additional attributes to be used when performing directory searches |
|
|
||||||
| `filter` | Specific user filter applied during directory search. |
|
|
||||||
| | Global filter is used if empty/blank/not set |
|
|
||||||
|
|
||||||
### Identity
|
|
||||||
Base path: `ldap.identity`
|
|
||||||
|
|
||||||
| Item | Description |
|
|
||||||
|----------|---------------------------------------------------------------------------------------------------|
|
|
||||||
| `filter` | Specific user filter applied during identity search. Global filter is used if empty/blank/not set |
|
|
||||||
| `medium` | Namespace to overwrite generated queries from the list of attributes for each 3PID medium |
|
|
@@ -1,23 +0,0 @@
|
|||||||
# SQL Backend
|
|
||||||
## Configuration
|
|
||||||
To be completed. For now, see default structure and values:
|
|
||||||
```
|
|
||||||
sql:
|
|
||||||
enabled: false
|
|
||||||
type: 'sqlite' or 'postgresql'
|
|
||||||
connection: ''
|
|
||||||
auth:
|
|
||||||
enabled: false
|
|
||||||
directory:
|
|
||||||
enabled: false
|
|
||||||
query:
|
|
||||||
name:
|
|
||||||
type: 'localpart'
|
|
||||||
value: 'SELECT 1'
|
|
||||||
threepid:
|
|
||||||
type: 'localpart'
|
|
||||||
value: 'SELECT 1'
|
|
||||||
identity:
|
|
||||||
type: 'localpart'
|
|
||||||
query: 'SELECT user_id AS uid FROM user_threepids WHERE medium = ? AND address = ?'
|
|
||||||
```
|
|
@@ -1,105 +1,73 @@
|
|||||||
# From source
|
# From source
|
||||||
- [Binaries](#binaries)
|
- [Binaries](#binaries)
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
- [Build](#build)
|
||||||
- [Debian package](#debian-package)
|
- [Debian package](#debian-package)
|
||||||
- [Docker image](#docker-image)
|
- [Docker image](#docker-image)
|
||||||
|
- [Next steps](#next-steps)
|
||||||
|
|
||||||
## Binaries
|
## Binaries
|
||||||
### Requirements
|
### Requirements
|
||||||
- JDK 1.8
|
- JDK 1.8
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
```
|
```bash
|
||||||
git clone https://github.com/kamax-io/mxisd.git
|
git clone https://github.com/kamax-matrix/mxisd.git
|
||||||
cd mxisd
|
cd mxisd
|
||||||
./gradlew build
|
./gradlew build
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new configuration file by coping `application.example.yaml` to `application.yaml` and edit to your needs.
|
Create a new configuration file by coping `application.example.yaml` to `application.yaml` and edit to your needs.
|
||||||
For advanced configuration, see the [Configure section](configure.md).
|
For advanced configuration, see the [Configure section](configure.md).
|
||||||
|
**NOTE**: `application.yaml` is also called `mxisd.yaml` in some specific installations.
|
||||||
|
|
||||||
Start the server in foreground to validate the build and configuration:
|
Start the server in foreground to validate the build and configuration:
|
||||||
```
|
```bash
|
||||||
java -jar build/libs/mxisd.jar
|
java -jar build/libs/mxisd.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Ensure the signing key is available:
|
Ensure the signing key is available:
|
||||||
```
|
```bash
|
||||||
$ curl 'http://localhost:8090/_matrix/identity/api/v1/pubkey/ed25519:0'
|
$ curl 'http://localhost:8090/_matrix/identity/api/v1/pubkey/ed25519:0'
|
||||||
{"public_key":"..."}
|
{"public_key":"..."}
|
||||||
```
|
```
|
||||||
|
|
||||||
Test basic recursive lookup (requires Internet connection with access to TCP 443):
|
Test basic recursive lookup (requires Internet connection with access to TCP 443):
|
||||||
```
|
```bash
|
||||||
$ curl 'http://localhost:8090/_matrix/identity/api/v1/lookup?medium=email&address=mxisd-lookup-test@kamax.io'
|
$ curl 'http://localhost:8090/_matrix/identity/api/v1/lookup?medium=email&address=mxisd-federation-test@kamax.io'
|
||||||
{"address":"mxisd-lookup-test@kamax.io","medium":"email","mxid":"@mxisd-lookup-test:kamax.io",...}
|
{"address":"mxisd-federation-test@kamax.io","medium":"email","mxid":"@mxisd-lookup-test:kamax.io",...}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you enabled LDAP, you can also validate your config with a similar request after replacing the `address` value with
|
If you enabled LDAP, you can also validate your config with a similar request after replacing the `address` value with
|
||||||
something present within your LDAP
|
something present within your LDAP
|
||||||
```
|
```bash
|
||||||
curl 'http://localhost:8090/_matrix/identity/api/v1/lookup?medium=email&address=john.doe@example.org'
|
curl 'http://localhost:8090/_matrix/identity/api/v1/lookup?medium=email&address=john.doe@example.org'
|
||||||
```
|
```
|
||||||
|
|
||||||
If you plan on testing the integration with a homeserver, you will need to run an HTTPS reverse proxy in front of it
|
If you plan on testing the integration with a homeserver, you will need to run an HTTPS reverse proxy in front of it
|
||||||
as the reference Home Server implementation [synapse](https://github.com/matrix-org/synapse) requires a HTTPS connection
|
as the reference Home Server implementation [synapse](https://github.com/matrix-org/synapse) requires a HTTPS connection
|
||||||
to an ID server.
|
to an ID server.
|
||||||
See the [Integration section](#integration) for more details.
|
|
||||||
|
|
||||||
### Install
|
Next step: [Install your compiled binaries](install/source.md)
|
||||||
1. Prepare files and directories:
|
|
||||||
```
|
|
||||||
# Create a dedicated user
|
|
||||||
useradd -r mxisd
|
|
||||||
|
|
||||||
# Create bin directory
|
|
||||||
mkdir /opt/mxisd
|
|
||||||
|
|
||||||
# Create config directory and set ownership
|
|
||||||
mkdir /etc/opt/mxisd
|
|
||||||
chown mxisd /etc/opt/mxisd
|
|
||||||
|
|
||||||
# Create data directory and set ownership
|
|
||||||
mkdir /var/opt/mxisd
|
|
||||||
chown mxisd /var/opt/mxisd
|
|
||||||
|
|
||||||
# Copy <repo root>/build/libs/mxisd.jar to bin directory
|
|
||||||
cp ./build/libs/mxisd.jar /opt/mxisd/
|
|
||||||
chown mxisd /opt/mxisd/mxisd.jar
|
|
||||||
chmod a+x /opt/mxisd/mxisd.jar
|
|
||||||
|
|
||||||
# Create symlink for easy exec
|
|
||||||
ln -s /opt/mxisd/mxisd.jar /usr/bin/mxisd
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Copy the sample config file `./application.example.yaml` to `/etc/opt/mxisd/mxisd.yaml`, edit to your needs
|
|
||||||
4. Copy `<repo root>/src/systemd/mxisd.service` to `/etc/systemd/system/` and edit if needed
|
|
||||||
5. Enable service for auto-startup
|
|
||||||
```
|
|
||||||
systemctl enable mxisd
|
|
||||||
```
|
|
||||||
6. Start mxisd
|
|
||||||
```
|
|
||||||
systemctl start mxisd
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debian package
|
## Debian package
|
||||||
### Requirements
|
Requirements:
|
||||||
- fakeroot
|
- fakeroot
|
||||||
- dpkg-deb
|
- dpkg-deb
|
||||||
|
|
||||||
### Build
|
|
||||||
[Build mxisd](#build) then:
|
[Build mxisd](#build) then:
|
||||||
```
|
```bash
|
||||||
./gradlew buildDeb
|
./gradlew buildDeb
|
||||||
```
|
```
|
||||||
You will find the debian package in `build/dist`
|
You will find the debian package in `build/dist`.
|
||||||
|
Then follow the instruction in the [Debian package](install/debian.md) document.
|
||||||
|
|
||||||
## Docker image
|
## Docker image
|
||||||
[Build mxisd](#build) then:
|
[Build mxisd](#build) then:
|
||||||
```
|
```bash
|
||||||
./gradlew dockerBuild
|
./gradlew dockerBuild
|
||||||
```
|
```
|
||||||
You can run a container of the given image and test it with the following command (adapt volumes host paths):
|
Then follow the instructions in the [Docker install](install/docker.md#configure) document.
|
||||||
```
|
|
||||||
docker run -v /data/mxisd/etc:/etc/mxisd -v /data/mxisd/var:/var/mxisd -p 8090:8090 -t kamax/mxisd:latest-dev
|
## Next steps
|
||||||
```
|
- [Integrate with your infrastructure](getting-started.md#integrate)
|
43
docs/concepts.md
Normal file
43
docs/concepts.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Concepts
|
||||||
|
- [Matrix](#matrix)
|
||||||
|
- [mxisd](#mxisd)
|
||||||
|
|
||||||
|
## Matrix
|
||||||
|
The following concepts are part of the Matrix ecosystem and specification.
|
||||||
|
|
||||||
|
### 3PID
|
||||||
|
`3PID` stands for Third-Party Identifier.
|
||||||
|
It is also commonly written:
|
||||||
|
- `3pid`
|
||||||
|
- `tpid`
|
||||||
|
|
||||||
|
A 3PID is a globally unique canonical identifier which is made of:
|
||||||
|
- Medium, which describes what network it belongs to (Email, Phone, Twitter, Discord, etc.)
|
||||||
|
- Address, the actual value people typically use on a daily basis.
|
||||||
|
|
||||||
|
mxisd core mission is to map those identifiers to Matrix User IDs.
|
||||||
|
|
||||||
|
### Homeserver
|
||||||
|
Where a user **account and data** are stored.
|
||||||
|
|
||||||
|
### Identity server
|
||||||
|
An Identity server:
|
||||||
|
- Does lookup of 3PIDs to User Matrix IDs.
|
||||||
|
- Does validate 3PIDs ownership, typically by sending a code that the user has to enter in an application/on a website.
|
||||||
|
- Does send notifications about room invites where no Matrix User ID could be found for the invitee.
|
||||||
|
|
||||||
|
An Identity server:
|
||||||
|
- **DOES NOT** store user accounts.
|
||||||
|
- **DOES NOT** store user data.
|
||||||
|
- **DOES NOT** allow migration of user account and/or data between homeservers.
|
||||||
|
|
||||||
|
### 3PID session
|
||||||
|
The fact to validate a 3PID (email, phone number, etc.) via the introduction of a token which was sent to the 3PID address.
|
||||||
|
|
||||||
|
## mxisd
|
||||||
|
The following concepts are specific to mxisd.
|
||||||
|
|
||||||
|
### Identity store
|
||||||
|
Where your user accounts and 3PID mappings are stored.
|
||||||
|
|
||||||
|
mxisd itself **DOES NOT STORE** user accounts or 3PID mappings.
|
@@ -1,18 +1,25 @@
|
|||||||
# Configuration
|
# Configuration
|
||||||
- [Syntax](#syntax)
|
- [Concepts](#concepts)
|
||||||
- [Variables](#variables)
|
- [Syntax](#syntax)
|
||||||
- [Categories](#categories)
|
- [Variables](#variables)
|
||||||
|
- [Matrix](#matrix)
|
||||||
|
- [Server](#server)
|
||||||
|
- [Storage](#storage)
|
||||||
|
- [Identity stores](#identity-stores)
|
||||||
|
- [3PID Validation sessions](#3pid-validation-sessions)
|
||||||
|
- [Notifications](#notifications)
|
||||||
|
|
||||||
## Syntax
|
## Concepts
|
||||||
The configuration file is YAML based, allowing two types of syntax.
|
### Syntax
|
||||||
|
The configuration file is [YAML](http://yaml.org/) based, allowing two types of syntax.
|
||||||
|
|
||||||
Properties-like:
|
Properties-like:
|
||||||
```
|
```yaml
|
||||||
my.config.item: 'value'
|
my.config.item: 'value'
|
||||||
```
|
```
|
||||||
|
|
||||||
Object-like:
|
Object-like:
|
||||||
```
|
```yaml
|
||||||
my:
|
my:
|
||||||
config:
|
config:
|
||||||
item: 'value'
|
item: 'value'
|
||||||
@@ -21,12 +28,10 @@ my:
|
|||||||
These can also be combined within the same file.
|
These can also be combined within the same file.
|
||||||
Both syntax will be used interchangeably in these documents.
|
Both syntax will be used interchangeably in these documents.
|
||||||
|
|
||||||
Default values for each possible option are documented [here](../src/main/resources/application.yaml)
|
### Variables
|
||||||
|
|
||||||
## Variables
|
|
||||||
It is possible to copy the value of a configuration item into another using the syntax `${config.key.item}`.
|
It is possible to copy the value of a configuration item into another using the syntax `${config.key.item}`.
|
||||||
Example that will copy the value of `matrix.domain` into `server.name`:
|
Example that will copy the value of `matrix.domain` into `server.name`:
|
||||||
```
|
```yaml
|
||||||
matrix:
|
matrix:
|
||||||
domain: 'example.org'
|
domain: 'example.org'
|
||||||
|
|
||||||
@@ -36,148 +41,62 @@ server:
|
|||||||
|
|
||||||
**WARNING:** mxisd might overwrite/adapt some values during launch. Those changes will not be reflected into copied keys.
|
**WARNING:** mxisd might overwrite/adapt some values during launch. Those changes will not be reflected into copied keys.
|
||||||
|
|
||||||
## Categories
|
|
||||||
For each category below, the base configuration path will be given, which needs to be appended to every configuration
|
|
||||||
item described.
|
|
||||||
|
|
||||||
Example: if the base path was `basePath` and the following table was given:
|
## Matrix
|
||||||
|
`matrix.domain`
|
||||||
| Name | Purpose |
|
Matrix domain name, same as the Homeserver, used to build appropriate Matrix IDs |
|
||||||
|------|---------|
|
|
||||||
| item1 | To give an example |
|
|
||||||
| item2 | To give another example |
|
|
||||||
|
|
||||||
The following configurations could be used, all being equivalent:
|
|
||||||
```
|
|
||||||
basePath.item1: 'myValue'
|
|
||||||
basePath.item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
```
|
|
||||||
basePath:
|
|
||||||
item1: 'myValue'
|
|
||||||
item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
```
|
|
||||||
basePath.item1: 'myValue'
|
|
||||||
basePath:
|
|
||||||
item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
In case a relative base path is given, it is appended to the one above.
|
`matrix.identity.servers`
|
||||||
|
Namespace to create arbitrary list of Identity servers, usable in other parts of the configuration |
|
||||||
Example: With base path `basePath`, the relative base `relativeBasePath` and the following table:
|
|
||||||
|
|
||||||
| Name | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| item1 | To give an example |
|
|
||||||
| item2 | To give another example |
|
|
||||||
|
|
||||||
The following configurations could be used, all being equivalent:
|
|
||||||
```
|
|
||||||
basePath.relativeBasePath.item1: 'myValue'
|
|
||||||
basePath.relativeBasePath.item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
```
|
|
||||||
basePath:
|
|
||||||
relativeBasePath:
|
|
||||||
item1: 'myValue'
|
|
||||||
item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
```
|
|
||||||
basePath.relativeBasePath.item1: 'myValue'
|
|
||||||
basePath:
|
|
||||||
relativeBasePath:
|
|
||||||
item2: 'myOtherValue'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Matrix
|
|
||||||
Base path: `matrix`
|
|
||||||
|
|
||||||
| Name | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `domain` | Matrix domain name, same as the Homeserver, used to build appropriate Matrix IDs |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Relative base path: `identity`
|
|
||||||
|
|
||||||
| Name | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `servers` | Namespace to create arbitrary list of Identity servers, usable in other parts of the configuration |
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```yaml
|
||||||
matrix.identity.servers:
|
matrix.identity.servers:
|
||||||
root:
|
myOtherServers:
|
||||||
- 'https://matrix.org'
|
- 'https://other1.example.org'
|
||||||
|
- 'https://other2.example.org'
|
||||||
```
|
```
|
||||||
Create a list under the label `root` containing a single Identity server, `https://matrix.org`
|
Create a list under the label `root` containing a single Identity server, `https://matrix.org`
|
||||||
### Server
|
|
||||||
| Name | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `name` | Public hostname of mxisd, if different from the Matrix domain |
|
|
||||||
| `port` | HTTP port to listen on (unencrypted) |
|
|
||||||
| `publicUrl` | Defaults to `https://${server.name}` |
|
|
||||||
|
|
||||||
### Storage
|
## Server
|
||||||
Base path: `storage`
|
- `server.name`: Public hostname of mxisd, if different from the Matrix domain.
|
||||||
|
- `server.port`: HTTP port to listen on (unencrypted)
|
||||||
|
- `server.publicUrl`: Defaults to `https://${server.name}`
|
||||||
|
|
||||||
| Name | Purpose |
|
## Storage
|
||||||
|------|---------|
|
### SQLite
|
||||||
| `backend` | Specify which SQL backend to use. only `sqlite` is currently supported. |
|
`storage.provider.sqlite.database`: Absolute location of the SQLite database
|
||||||
|
|
||||||
---
|
## Identity stores
|
||||||
Relative base path: `provider.sqlite`
|
See the [Identity stores](stores/README.md) for specific configuration
|
||||||
|
|
||||||
| Name | Purpose |
|
## 3PID Validation sessions
|
||||||
|------|---------|
|
See the dedicated documents:
|
||||||
| `database` | Absolute location of the SQLite database |
|
- [Flow](threepids/session/session.md)
|
||||||
|
- [Branding](threepids/session/session-views.md)
|
||||||
|
|
||||||
### Backends
|
## Notifications
|
||||||
- [LDAP](backends/ldap.md)
|
- `notification.handler.<3PID medium>`: Handler to use for the given 3PID medium. Repeatable.
|
||||||
- [SQL](backends/sql.md)
|
|
||||||
- [REST](backends/rest.md)
|
|
||||||
- [Google Firebase](backends/firebase.md)
|
|
||||||
|
|
||||||
### Lookups
|
|
||||||
work in progress, should not be configured.
|
|
||||||
|
|
||||||
### Sessions
|
|
||||||
See the [dedicated document](sessions/3pid.md)
|
|
||||||
|
|
||||||
### Notifications
|
|
||||||
Base path: `notification`
|
|
||||||
|
|
||||||
| Name | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| handler | Namespace to specify the handler to use for each 3PID |
|
|
||||||
| handlers | Namespace used by individual handlers for their own configuration |
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
```yaml
|
||||||
|
notification.handler.email: 'sendgrid'
|
||||||
|
notification.handler.msisdn: 'raw'
|
||||||
```
|
```
|
||||||
notification:
|
- Emails notifications would use the `sendgrid` handler, which define its own configuration under `notification.handlers.sendgrid`
|
||||||
handler:
|
|
||||||
email: 'sendgrid'
|
|
||||||
msisdn: 'raw'
|
|
||||||
handlers:
|
|
||||||
raw:
|
|
||||||
...
|
|
||||||
sendgrid:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
- Emails notifications would use the `sendgrid` handler, which define its own configuration user `handlers.sendgrid`
|
|
||||||
- Phone notification would use the `raw` handler, basic default built-in handler of mxisd
|
- Phone notification would use the `raw` handler, basic default built-in handler of mxisd
|
||||||
#### Handlers
|
|
||||||
Relative base path: `handlers`
|
### Handlers
|
||||||
|
- `notification.handers.<handler ID>`: Handler-specific configuration for the given handler ID. Repeatable.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
notification.handlers.raw: ...
|
||||||
|
notification.handlers.sendgrid: ...
|
||||||
|
```
|
||||||
|
|
||||||
Built-in:
|
Built-in:
|
||||||
- [Basic](threepids/notifications/basic-handler.md)
|
- [Raw](threepids/notification/basic-handler.md)
|
||||||
- [SendGrid](threepids/notifications/sendgrid-handler.md)
|
- [SendGrid](threepids/notification/sendgrid-handler.md)
|
||||||
|
|
||||||
### Views
|
|
||||||
See the [dedicated document](sessions/3pid-views.md)
|
|
||||||
|
|
||||||
### DNS Overwite
|
|
||||||
Specific to other features.
|
|
||||||
|
82
docs/faq.md
82
docs/faq.md
@@ -1,9 +1,27 @@
|
|||||||
# FAQ
|
# Frequently Asked Questions
|
||||||
### Do I need to use mxisd if I run a Homeserver?
|
### This is all very complicated and I'm getting confused with all the words, concepts and diagrams - Help!
|
||||||
No, but it is recommended, even if you don't use any backends or integration.
|
Matrix is still a very young protocol and there are a whole lot of rough edges.
|
||||||
|
Identity in Matrix is one of the most difficult topic, mainly as it has not received much love in the past years.
|
||||||
|
|
||||||
In its default configuration, mxisd will talk to the central Matrix Identity servers and use other federated public
|
We have tried our best to put together documentation that requires almost no knowledge of Matrix inner workings to get a
|
||||||
servers when performing queries, giving you access to at least the same information as if you were not running it.
|
first basic setup running which relies on you reading the documentation in the right order:
|
||||||
|
- [The Concepts](concepts.md) in few words.
|
||||||
|
- [Getting Started](getting-started.md) step-by-step to a minimal working install.
|
||||||
|
- [Identity stores](stores/README.md) you wish to fetch data from.
|
||||||
|
- [Features](features) you are interested in that will use your Identity store(s) data.
|
||||||
|
|
||||||
|
**IMPORTANT**: Be aware that mxisd tries to fit within the current protocol and existing products and basic understanding
|
||||||
|
of the Matrix protocol is required for some advanced features.
|
||||||
|
|
||||||
|
If all fails, come over to [the project room](https://matrix.to/#/#mxisd:kamax.io) and we'll do our best to get you
|
||||||
|
started and answer questions you might have.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
In its default configuration, mxisd uses other federated public servers when performing queries.
|
||||||
|
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.
|
||||||
@@ -11,7 +29,24 @@ privacy consequences, which is not the case with the central Matrix.org servers.
|
|||||||
So mxisd is like your gatekeeper and guardian angel. It does not change what you already know, just adds some nice
|
So mxisd is like your gatekeeper and guardian angel. It does not change what you already know, just adds some nice
|
||||||
simple features on top of it.
|
simple features on top of it.
|
||||||
|
|
||||||
### I already use the synapse LDAP3 auth provider, why should I care about mxisd?
|
### I'm not sure I understand what an "Identity server" is supposed to be or do...
|
||||||
|
The current Identity service API is more a placeholder, as the Matrix devs did not have time so far to really work on
|
||||||
|
what they want to do with that part of the ecosystem. Therefore, "Identity" is currently a misleading word and concept.
|
||||||
|
Given the scope of the current Identity Service API, it would be best called "Invitation service".
|
||||||
|
|
||||||
|
Because the current scope is so limited and no integration is done with the Homeserver, there was a big lack of features
|
||||||
|
for groups/corporations/organisation. This is where mxisd comes in.
|
||||||
|
|
||||||
|
mxisd implements the Identity Service API and also a set of features which are expected by regular users, truly living
|
||||||
|
up to its "Identity server" name.
|
||||||
|
|
||||||
|
### Can I migrate my existing account on another Matrix server with mxisd?
|
||||||
|
No.
|
||||||
|
|
||||||
|
Accounts cannot currently migrate/move from one server to another.
|
||||||
|
See a [brief explanation document](concepts.md) about Matrix and mxisd concepts and vocabulary.
|
||||||
|
|
||||||
|
### I already use the synapse LDAP3 auth provider. Why should I care about mxisd?
|
||||||
The [synapse LDAP3 auth provider](https://github.com/matrix-org/matrix-synapse-ldap3) is not longer maintained and
|
The [synapse LDAP3 auth provider](https://github.com/matrix-org/matrix-synapse-ldap3) is not longer maintained and
|
||||||
only handles on specific flow: validate credentials at login.
|
only handles on specific flow: validate credentials at login.
|
||||||
|
|
||||||
@@ -19,12 +54,11 @@ It does not:
|
|||||||
- Auto-provision user profiles
|
- Auto-provision user profiles
|
||||||
- Integrate with Identity management
|
- Integrate with Identity management
|
||||||
- Integrate with Directory searches
|
- Integrate with Directory searches
|
||||||
- Protect you against the username case sensitivites issues in synapse
|
|
||||||
|
|
||||||
mxisd is a replacement and enhancement of it, offering coherent results in all areas, which LDAP3 auth provider
|
mxisd is a replacement and enhancement of it, offering coherent results in all areas, which the LDAP3 auth provider
|
||||||
does not.
|
does not.
|
||||||
|
|
||||||
### Sydent is the official Identity server implementation of the Matrix team, why not use that?
|
### Sydent is the official Identity server implementation of the Matrix team. Why not use that?
|
||||||
You can, but [sydent](https://github.com/matrix-org/sydent):
|
You can, but [sydent](https://github.com/matrix-org/sydent):
|
||||||
- [should not be used and/or self-hosted](https://github.com/matrix-org/sydent/issues/22)
|
- [should not be used and/or self-hosted](https://github.com/matrix-org/sydent/issues/22)
|
||||||
- is not meant to be linked to a specific Homeserver / domain
|
- is not meant to be linked to a specific Homeserver / domain
|
||||||
@@ -35,31 +69,19 @@ You can, but [sydent](https://github.com/matrix-org/sydent):
|
|||||||
So really, you should go with mxisd.
|
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?
|
||||||
In its default configuration, mxisd act as a proxy to Matrix.org/Vector.im. You will have access to the same data and
|
No.
|
||||||
behaviour than if you were using them directly. There is no downside in using mxisd with the default configuration.
|
|
||||||
|
|
||||||
mxisd can also be configured not to talk to the central Identity servers if you wish.
|
In its default configuration, mxisd does not talk to the central Identity server matrix.org to avoid leaking your private
|
||||||
|
data and those of people you might know.
|
||||||
|
|
||||||
### I'm not sure I understand what an "Identity server" is supposed to be or do
|
mxisd [can be configured](features/identity.md#lookups) to talk to the central Identity servers if you wish.
|
||||||
The current Identity service API is more a placeholder, as the Matrix devs did not have time so far to really work on
|
|
||||||
what they want to do with that part of the ecosystem. Therefore, "Identity" is a misleading word currently.
|
|
||||||
Given the scope of the current Identity Service API, it would be best called "Invitation service".
|
|
||||||
|
|
||||||
Because the current scope is so limited and no integration is done with the Homeserver, there was a big lack of features
|
|
||||||
for groups/corporations/organisation. This is where mxisd comes in.
|
|
||||||
|
|
||||||
mxisd implements the Identity Service API and also a set of features which are expected by regular users, truly living
|
|
||||||
up to its "Identity server" name.
|
|
||||||
|
|
||||||
### 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.
|
||||||
|
|
||||||
We also directly talk with the Matrix developers to ensure all features we implement have their approval, and that we
|
|
||||||
are in line with their vision of Identity management within the Matrix 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 very nice 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.
|
||||||
|
|
||||||
|
It is possible, but it is not supported and the scope of features will be extremely limited.
|
||||||
|
Please consider hosting your own Homeserver and using mxisd alongside it.
|
||||||
|
@@ -1,60 +1,59 @@
|
|||||||
# Authentication
|
# Authentication
|
||||||
|
|
||||||
- [Description](#description)
|
- [Description](#description)
|
||||||
- [Overview](#overview)
|
- [Basic](#basic)
|
||||||
- [Getting started](#getting-started)
|
- [Overview](#overview)
|
||||||
- [Synapse](#synapse)
|
- [synapse](#synapse)
|
||||||
- [mxisd](#mxisd)
|
- [mxisd](#mxisd)
|
||||||
- [Validate](#validate)
|
- [Validate](#validate)
|
||||||
- [Next steps](#next-steps)
|
- [Next steps](#next-steps)
|
||||||
- [Profile auto-fil](#profile-auto-fill)
|
- [Profile auto-fil](#profile-auto-fill)
|
||||||
- [Advanced Authentication](#advanced-authentication)
|
- [Advanced](#advanced)
|
||||||
|
- [Overview](#overview-1)
|
||||||
- [Requirements](#requirements)
|
- [Requirements](#requirements)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Reverse Proxy](#reverse-proxy)
|
- [Reverse Proxy](#reverse-proxy)
|
||||||
- [Apache2](#apache2)
|
- [Apache2](#apache2)
|
||||||
- [DNS Overwrite](#dns-overwrite)
|
- [DNS Overwrite](#dns-overwrite)
|
||||||
- [Backends](#backends)
|
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
Authentication is an enhanced Identity feature of mxisd to ensure coherent and centralized identity management.
|
Authentication is an enhanced feature of mxisd to ensure coherent and centralized identity management.
|
||||||
|
|
||||||
It allows to use Identity stores configured in mxisd to authenticate users on your Homeserver.
|
It allows to use Identity stores configured in mxisd to authenticate users on your Homeserver.
|
||||||
|
|
||||||
This feature can also provide the ability to users to login on the Homeserver using their third party identities (3PIDs) provided by an Identity store.
|
Authentication is divided into two parts:
|
||||||
|
- [Basic](#basic): authenticate with a regular username.
|
||||||
|
- [Advanced](#advanced): same as basic with extra ability to authenticate using a 3PID.
|
||||||
|
|
||||||
## Overview
|
## Basic
|
||||||
An overview of the Authentication process is depicted below:
|
Authentication by username is possible by linking synapse and mxisd together using a specific module for synapse, also
|
||||||
|
known as password provider.
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
An overview of the Basic Authentication process:
|
||||||
```
|
```
|
||||||
Backends
|
Identity stores
|
||||||
Client +------+
|
Client +------+
|
||||||
| +-------------------------+ +--> | LDAP |
|
| +-------------------------+ +--> | LDAP |
|
||||||
| +---------------+ /_matrix/identity | mxisd | | +------+
|
| +---------------+ /_matrix/identity | mxisd | | +------+
|
||||||
+-> | Reverse proxy | >------------------+ | | |
|
+-> | Reverse proxy | >------------------+ | | |
|
||||||
+--|------------+ | | | | +--------+
|
+--|------------+ | | | | +--------+
|
||||||
| +-----> Check with backends >------+--> | SQL DB |
|
| +-----> Check ID stores >------+--> | SQL DB |
|
||||||
Login request | | | | +--------+
|
Login request | | | | +--------+
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| +--------------------------+ | +-----|-------------------+ +--> Others
|
| +--------------------------+ | +-----|-------------------+ +--> ...
|
||||||
+-> | Homeserver | | |
|
+-> | Homeserver | | |
|
||||||
| | | |
|
| | | |
|
||||||
| - Validate credentials >----+ |
|
| - Validate credentials >----+ |
|
||||||
| Using REST auth module | |
|
| Using REST auth module | |
|
||||||
| | |
|
| | |
|
||||||
| - Auto-provision <-------------------<+
|
| - Auto-provision <-------------------<+
|
||||||
| user profiles | If valid credentials and supported by backend
|
| user profiles | If valid credentials and supported by Identity store(s)
|
||||||
+--------------------------+
|
+--------------------------+
|
||||||
```
|
```
|
||||||
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
|
|
||||||
Authentication is possible by linking synapse and mxisd together using the REST auth module
|
|
||||||
(also known as password provider).
|
|
||||||
|
|
||||||
### Synapse
|
### Synapse
|
||||||
- Install the [REST auth module](https://github.com/kamax-io/matrix-synapse-rest-auth).
|
- Install the [password provider](https://github.com/kamax-io/matrix-synapse-rest-auth)
|
||||||
- Edit your synapse configuration:
|
- Edit your **synapse** configuration:
|
||||||
- As described by the auth module documentation
|
- As described by the auth module documentation
|
||||||
- Set `endpoint` to `http://mxisdAddress:8090` - Replace `mxisdAddress` by an IP/host name that provides a direct
|
- Set `endpoint` to `http://mxisdAddress:8090` - Replace `mxisdAddress` by an IP/host name that provides a direct
|
||||||
connection to mxisd.
|
connection to mxisd.
|
||||||
@@ -62,25 +61,23 @@ Authentication is possible by linking synapse and mxisd together using the REST
|
|||||||
- Restart synapse
|
- Restart synapse
|
||||||
|
|
||||||
### mxisd
|
### mxisd
|
||||||
- Configure and enable at least one [Identity store](../backends/)
|
- Configure and enable at least one [Identity store](../stores/README.md)
|
||||||
- Restart mxisd
|
- Restart mxisd
|
||||||
|
|
||||||
### Validate
|
### Validate
|
||||||
Login on the Homeserver using credentials present in your backend.
|
Login on the Homeserver using credentials present in one of your Identity stores.
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
### Profile auto-fill
|
### Profile auto-fill
|
||||||
Auto-filling user profile depends on two conditions:
|
Auto-filling user profile depends on its support by your configured Identity stores.
|
||||||
- The REST auth module is configured for it, which is the case by default
|
See your Identity store [documentation](../stores/README.md) on how to enable the feature.
|
||||||
- Your Identity store is configured to provide profile data. See your Identity store [documentation](../backends/) on
|
|
||||||
how to enable the feature.
|
|
||||||
|
|
||||||
|
|
||||||
## Advanced Authentication
|
## Advanced
|
||||||
The Authentication feature allows users to login to their Homeserver by using their 3PIDs registered in an available Identity store.
|
The Authentication feature allows users to login to their Homeserver by using their 3PIDs in a configured Identity store.
|
||||||
|
|
||||||
|
### Overview
|
||||||
This is performed by intercepting the Homeserver endpoint `/_matrix/client/r0/login` as depicted below:
|
This is performed by intercepting the Homeserver endpoint `/_matrix/client/r0/login` as depicted below:
|
||||||
|
|
||||||
```
|
```
|
||||||
+----------------------------+
|
+----------------------------+
|
||||||
| Reverse Proxy |
|
| Reverse Proxy |
|
||||||
@@ -106,31 +103,28 @@ Client+---->| /_matrix/client/r0/login +---------------->|
|
|||||||
|
|
||||||
Steps of user authentication using a 3PID:
|
Steps of user authentication using a 3PID:
|
||||||
1. The intercepted login request is directly sent to mxisd instead of the Homeserver.
|
1. The intercepted login request is directly sent to mxisd instead of the Homeserver.
|
||||||
2. Enabled backends are queried for a matching user identity in order to modify the request to use the user name.
|
2. Identity stores are queried for a matching user identity in order to modify the request to use the user name.
|
||||||
3. The Homeserver, from which the request was intercepted, is queried using the request at previous step. Its address is resolved using the DNS Overwrite feature to reach its internal address on a non-encrypted port.
|
3. The Homeserver, from which the request was intercepted, is queried using the request at previous step.
|
||||||
|
Its address is resolved using the DNS Overwrite feature to reach its internal address on a non-encrypted port.
|
||||||
4. The response from the Homeserver is sent back to the client, believing it was the HS which directly answered.
|
4. The response from the Homeserver is sent back to the client, believing it was the HS which directly answered.
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
- [Basic Authentication configured and working](#basic)
|
||||||
- Reverse proxy setup
|
- Reverse proxy setup
|
||||||
- Homeserver
|
- Homeserver
|
||||||
- Compatible Identity backends:
|
- Compatible [Identity store](../stores/README.md)
|
||||||
- LDAP
|
|
||||||
- REST
|
|
||||||
- Wordpress
|
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
#### Reverse Proxy
|
#### Reverse Proxy
|
||||||
|
|
||||||
##### Apache2
|
##### Apache2
|
||||||
The specific configuration to put under the relevant `VirtualHost`:
|
The specific configuration to put under the relevant `VirtualHost`:
|
||||||
```
|
```apache
|
||||||
ProxyPass /_matrix/client/r0/login http://localhost:8090/_matrix/client/r0/login
|
ProxyPass /_matrix/client/r0/login http://localhost:8090/_matrix/client/r0/login
|
||||||
```
|
```
|
||||||
`ProxyPreserveHost` or equivalent must be enabled to detect to which Homeserver mxisd should talk to when building results.
|
`ProxyPreserveHost` or equivalent **must** be enabled to detect to which Homeserver mxisd should talk to when building results.
|
||||||
|
|
||||||
Your VirtualHost should now look like this:
|
Your VirtualHost should now look similar to:
|
||||||
```
|
```apache
|
||||||
<VirtualHost *:443>
|
<VirtualHost *:443>
|
||||||
ServerName example.org
|
ServerName example.org
|
||||||
|
|
||||||
@@ -138,25 +132,24 @@ Your VirtualHost should now look like this:
|
|||||||
|
|
||||||
ProxyPreserveHost on
|
ProxyPreserveHost on
|
||||||
ProxyPass /_matrix/client/r0/login http://localhost:8090/_matrix/client/r0/login
|
ProxyPass /_matrix/client/r0/login http://localhost:8090/_matrix/client/r0/login
|
||||||
ProxyPass /_matrix/identity/ http://localhost:8090/_matrix/identity/
|
ProxyPass /_matrix/identity http://localhost:8090/_matrix/identity
|
||||||
ProxyPass /_matrix/ http://localhost:8008/_matrix/
|
ProxyPass /_matrix http://localhost:8008/_matrix
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### DNS Overwrite
|
#### DNS Overwrite
|
||||||
Just like you need to configure a reverse proxy to send client requests to mxisd, you also need to configure mxisd with the internal IP of the Homeserver so it can talk to it directly to integrate its directory search.
|
Just like you need to configure a reverse proxy to send client requests to mxisd, you also need to configure mxisd with
|
||||||
|
the internal IP of the Homeserver so it can talk to it directly to integrate its directory search.
|
||||||
|
|
||||||
|
To do so, put the following configuration in your mxisd configuration:
|
||||||
To do so, put the following configuration in your `application.yaml`:
|
```yaml
|
||||||
```
|
|
||||||
dns.overwrite.homeserver.client:
|
dns.overwrite.homeserver.client:
|
||||||
- name: 'example.org'
|
- name: 'example.org'
|
||||||
value: 'http://localhost:8008'
|
value: 'http://localhost:8008'
|
||||||
```
|
```
|
||||||
`name` must be the hostname of the URL that clients use when connecting to the Homeserver.
|
`name` must be the hostname of the URL that clients use when connecting to the Homeserver.
|
||||||
In case the hostname is the same as your Matrix domain, you can use `${matrix.domain}` to auto-populate the `value` using the `matrix.domain` configuration option and avoid duplicating it.
|
You can use `${server.name}` to auto-populate the `value` using the `server.name` configuration option and avoid duplicating it.
|
||||||
|
In case the hostname is the same as your Matrix domain and `server.name` is not explicitely set in the config, `server.name` will default to
|
||||||
|
`matrix.domain` and will still probably have the correct value.
|
||||||
|
|
||||||
value is the base internal URL of the Homeserver, without any /_matrix/.. or trailing /.
|
`value` is the base internal URL of the Homeserver, without any `/_matrix/..` or trailing `/`.
|
||||||
|
|
||||||
#### Backends
|
|
||||||
The Backends should be configured as described in the documentation of the [Directory User](directory-users.md) feature.
|
|
||||||
|
@@ -1 +1,28 @@
|
|||||||
To be documented
|
# Bridge Integration
|
||||||
|
To help natural bridge integration into the regular usage of a Matrix client, mxisd provides a way for bridge to reply
|
||||||
|
to 3PID queries if no mapping was found, allowing seamless bridging to a network.
|
||||||
|
|
||||||
|
This is performed by implementing a specific endpoint on the bridge to map a 3PID lookup to a virtual user.
|
||||||
|
|
||||||
|
**NOTE**: This document is incomplete and might be misleading. In doubt, come in our Matrix room.
|
||||||
|
You can also look at our [Email Bridge README](https://github.com/kamax-io/matrix-appservice-email#mxisd) for an example
|
||||||
|
of working configuration.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
```yaml
|
||||||
|
lookup.recursive.bridge.enabled: <boolean>
|
||||||
|
lookup.recursive.bridge.recursiveOnly: <boolean>
|
||||||
|
lookup.recursive.bridge.server: <URL to the bridge endpoint for all 3PID medium>
|
||||||
|
lookup.recursive.bridge.mappings:
|
||||||
|
<3PID MEDIUM HERE>: <URL to dedicated bridge for that medium>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
Implement a simplified version of the [Identity service single lookup endpoint](https://kamax.io/matrix/api/identity_service/unstable.html#get-matrix-identity-api-v1-lookup)
|
||||||
|
with only the following parameters needed:
|
||||||
|
- `address`
|
||||||
|
- `medium`
|
||||||
|
- `mxid`
|
||||||
|
|
||||||
|
Or an empty object if no resolution exists or desired.
|
||||||
|
@@ -7,10 +7,6 @@
|
|||||||
- [Apache2](#apache2)
|
- [Apache2](#apache2)
|
||||||
- [nginx](#nginx)
|
- [nginx](#nginx)
|
||||||
- [DNS Overwrite](#dns-overwrite)
|
- [DNS Overwrite](#dns-overwrite)
|
||||||
- [Backends](#backends)
|
|
||||||
- [LDAP](#ldap)
|
|
||||||
- [SQL](#sql)
|
|
||||||
- [REST](#rest)
|
|
||||||
- [Next steps](#next-steps)
|
- [Next steps](#next-steps)
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
@@ -18,17 +14,17 @@ This feature allows you to search for existing and/or potential users that are a
|
|||||||
or that already share a room with you on the Homeserver.
|
or that already share a room with you on the Homeserver.
|
||||||
|
|
||||||
Without any integration, synapse:
|
Without any integration, synapse:
|
||||||
- Only search within the users **already** known to you
|
- Only search within the users **already** known to you or in public rooms
|
||||||
- Only search on the Display Name and the Matrix ID
|
- Only search on the Display Name and the Matrix ID
|
||||||
|
|
||||||
With mxisd integration, you can:
|
By enabling this feature, you can by default:
|
||||||
- Search on Matrix ID, Display name and 3PIDs (Email, phone numbers) of any users already in your configured backend
|
- Search on Matrix ID, Display name and 3PIDs (Email, phone numbers) of any users already in your configured backend
|
||||||
- Search for users which you are not in contact with yet. Super useful for corporations who want to give Matrix access
|
- Search for users which you are not in contact with yet. Super useful for corporations who want to give Matrix access
|
||||||
internally, so users can just find themselves **prior** to having any common room(s)
|
internally, so users can just find themselves **prior** to having any common room(s)
|
||||||
- Use any attribute of your backend to extend the search!
|
- Add extra attributes of your backend to extend the search
|
||||||
- Include your homeserver search results to those found by mxisd (default behaviour, no configuration required)
|
- Include your homeserver search results to those found by mxisd
|
||||||
|
|
||||||
By integrating mxisd, you get the default behaviour with all the extras, ensuring your users will always find each other.
|
By integrating mxisd, you get the default behaviour and a bunch of extras, ensuring your users will always find each other.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
This is performed by intercepting the Homeserver endpoint `/_matrix/client/r0/user_directory/search` like so:
|
This is performed by intercepting the Homeserver endpoint `/_matrix/client/r0/user_directory/search` like so:
|
||||||
@@ -49,31 +45,28 @@ Client --> | Reverse proxy
|
|||||||
```
|
```
|
||||||
Steps:
|
Steps:
|
||||||
1. The intercepted request is directly sent to mxisd instead of the Homeserver.
|
1. The intercepted request is directly sent to mxisd instead of the Homeserver.
|
||||||
2. Enabled backends are queried for any match on the search value sent by the client.
|
2. Identity stores are queried for any match on the search value sent by the client.
|
||||||
3. The Homeserver, from which the request was intercepted, is queried using the same request as the client.
|
3. The Homeserver, from which the request was intercepted, is queried using the same request as the client.
|
||||||
Its address is resolved using the DNS Overwrite feature to reach its internal address on a non-encrypted port.
|
Its address is resolved using the DNS Overwrite feature to reach its internal address on a non-encrypted port.
|
||||||
4. Results from backends and the Homeserver are merged together and sent back to the client, believing it was the HS
|
4. Results from Identity stores and the Homeserver are merged together and sent back to the client, believing it was the HS
|
||||||
which directly answered the request.
|
which directly answered the request.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- Reverse proxy setup, which you should already have in place if you use mxisd
|
- Reverse proxy setup, which you should already have in place if you use mxisd
|
||||||
- Compatible backends:
|
- At least one compatible [Identity store](../stores/README.md) enabled
|
||||||
- LDAP
|
|
||||||
- SQL
|
|
||||||
- REST
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
### Reverse Proxy
|
### Reverse Proxy
|
||||||
#### Apache2
|
#### Apache2
|
||||||
The specific configuration to put under the relevant `VirtualHost`:
|
The specific configuration to put under the relevant `VirtualHost`:
|
||||||
```
|
```apache
|
||||||
ProxyPass /_matrix/client/r0/user_directory/ http://0.0.0.0:8090/_matrix/client/r0/user_directory/
|
ProxyPass /_matrix/client/r0/user_directory/ http://0.0.0.0:8090/_matrix/client/r0/user_directory/
|
||||||
```
|
```
|
||||||
`ProxyPreserveHost` or equivalent must be enabled to detect to which Homeserver mxisd should talk to when building
|
`ProxyPreserveHost` or equivalent must be enabled to detect to which Homeserver mxisd should talk to when building
|
||||||
results.
|
results.
|
||||||
|
|
||||||
Your `VirtualHost` should now look like this:
|
Your `VirtualHost` should now look like this:
|
||||||
```
|
```apache
|
||||||
<VirtualHost *:443>
|
<VirtualHost *:443>
|
||||||
ServerName example.org
|
ServerName example.org
|
||||||
|
|
||||||
@@ -81,14 +74,14 @@ Your `VirtualHost` should now look like this:
|
|||||||
|
|
||||||
ProxyPreserveHost on
|
ProxyPreserveHost on
|
||||||
ProxyPass /_matrix/client/r0/user_directory/ http://localhost:8090/_matrix/client/r0/user_directory/
|
ProxyPass /_matrix/client/r0/user_directory/ http://localhost:8090/_matrix/client/r0/user_directory/
|
||||||
ProxyPass /_matrix/identity/ http://localhost:8090/_matrix/identity/
|
ProxyPass /_matrix/identity http://localhost:8090/_matrix/identity
|
||||||
ProxyPass /_matrix/ http://localhost:8008/_matrix/
|
ProxyPass /_matrix http://localhost:8008/_matrix
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### nginx
|
#### nginx
|
||||||
The specific configuration to add under your `server` section is:
|
The specific configuration to add under your `server` section is:
|
||||||
```
|
```nginx
|
||||||
location /_matrix/client/r0/user_directory {
|
location /_matrix/client/r0/user_directory {
|
||||||
proxy_pass http://0.0.0.0:8090/_matrix/client/r0/user_directory;
|
proxy_pass http://0.0.0.0:8090/_matrix/client/r0/user_directory;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -97,7 +90,7 @@ location /_matrix/client/r0/user_directory {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Your `server` section should now look like this:
|
Your `server` section should now look like this:
|
||||||
```
|
```nginx
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name example.org;
|
server_name example.org;
|
||||||
@@ -129,7 +122,7 @@ Just like you need to configure a reverse proxy to send client requests to mxisd
|
|||||||
the internal IP of the Homeserver so it can talk to it directly to integrate its directory search.
|
the internal IP of the Homeserver so it can talk to it directly to integrate its directory search.
|
||||||
|
|
||||||
To do so, use the following configuration:
|
To do so, use the following configuration:
|
||||||
```
|
```yaml
|
||||||
dns.overwrite.homeserver.client:
|
dns.overwrite.homeserver.client:
|
||||||
- name: 'example.org'
|
- name: 'example.org'
|
||||||
value: 'http://localhost:8008'
|
value: 'http://localhost:8008'
|
||||||
@@ -138,94 +131,19 @@ dns.overwrite.homeserver.client:
|
|||||||
In case the hostname is the same as your Matrix domain, you can use `${matrix.domain}` to auto-populate the value using
|
In case the hostname is the same as your Matrix domain, you can use `${matrix.domain}` to auto-populate the value using
|
||||||
the `matrix.domain` configuration option and avoid duplicating it.
|
the `matrix.domain` configuration option and avoid duplicating it.
|
||||||
|
|
||||||
`value` is the base intenral URL of the Homeserver, without any `/_matrix/..` or trailing `/`.
|
`value` is the base internal URL of the Homeserver, without any `/_matrix/..` or trailing `/`.
|
||||||
|
|
||||||
### Backends
|
|
||||||
#### LDAP
|
|
||||||
To ensure Directory feature works, here's how the LDAP configuration should look like:
|
|
||||||
```
|
|
||||||
ldap:
|
|
||||||
enabled: false
|
|
||||||
filter: '(memberOf=CN=Matrix Users,OU=Groups,DC=example,DC=org)'
|
|
||||||
connection:
|
|
||||||
host: 'ldapIpOrDomain'
|
|
||||||
bindDn: 'CN=Matrix Identity Server,OU=Accounts,DC=example,DC=org'
|
|
||||||
bindPassword: 'mxisd'
|
|
||||||
baseDn: 'OU=Accounts,DC=example,DC=org'
|
|
||||||
attribute:
|
|
||||||
uid:
|
|
||||||
type: 'uid'
|
|
||||||
value: 'userPrincipalName'
|
|
||||||
name: 'displayName'
|
|
||||||
threepid:
|
|
||||||
email:
|
|
||||||
- 'mailPrimaryAddress'
|
|
||||||
- 'mail'
|
|
||||||
- 'otherMailbox'
|
|
||||||
msisdn:
|
|
||||||
- 'telephoneNumber'
|
|
||||||
- 'mobile'
|
|
||||||
- 'homePhone'
|
|
||||||
- 'otherTelephone'
|
|
||||||
- 'otherMobile'
|
|
||||||
- 'otherHomePhone'
|
|
||||||
directory:
|
|
||||||
attribute:
|
|
||||||
other:
|
|
||||||
- 'employeeNumber'
|
|
||||||
- 'someOtherAttribute'
|
|
||||||
```
|
|
||||||
Only include the `attribute` sub-sections if you would like to set another value. Else, it is best not to include them
|
|
||||||
to inherit the default values.
|
|
||||||
|
|
||||||
If you would like to include an attribute which is not a display name or a 3PID, you can use the
|
|
||||||
`directory.attribute.other` to list any extra attributes you want included in searches. If you do not want to include
|
|
||||||
any extra attribute, that configuration section can be skipped.
|
|
||||||
|
|
||||||
#### SQL
|
|
||||||
If you plan to integrate directory search directly with synapse, use the `synapseSql` provider, based on the following
|
|
||||||
config:
|
|
||||||
```
|
|
||||||
synapseSql:
|
|
||||||
enabled: true
|
|
||||||
type: <database ID>
|
|
||||||
connection: '<connection info>'
|
|
||||||
```
|
|
||||||
`type` and `connection`, including any other configuration item, follow the same values as the regular [SQL backend](../backends/sql.md).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
For the regular SQL backend, the following configuration items are available:
|
|
||||||
```
|
|
||||||
sql:
|
|
||||||
directory:
|
|
||||||
enabled: true
|
|
||||||
query:
|
|
||||||
name:
|
|
||||||
type: 'localpart'
|
|
||||||
value: 'SELECT idColumn, displayNameColumn FROM table WHERE displayNameColumn LIKE ?'
|
|
||||||
threepid:
|
|
||||||
type: 'localpart'
|
|
||||||
value: 'SELECT idColumn, displayNameColumn FROM table WHERE threepidColumn LIKE ?'
|
|
||||||
```
|
|
||||||
For each query, `type` can be used to tell mxisd how to process the ID column:
|
|
||||||
- `localpart` will append the `matrix.domain` to it
|
|
||||||
- `mxid` will use the ID as-is. If it is not a valid Matrix ID, the search will fail.
|
|
||||||
|
|
||||||
`value` is the SQL query and must return two columns:
|
|
||||||
- The first being the User ID
|
|
||||||
- The second being its display name
|
|
||||||
|
|
||||||
#### REST
|
|
||||||
See the [dedicated document](../backends/rest.md)
|
|
||||||
|
|
||||||
#### Wordpress
|
|
||||||
See the [dedicated document](../backends/wordpress.md)
|
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
### Homeserver results
|
### Homeserver results
|
||||||
You can configure if the Homeserver should be queried at all when doing a directory search.
|
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:
|
To disable Homeserver results, set the following in mxisd configuration file:
|
||||||
|
```yaml
|
||||||
|
directory.exclude.homeserver: true
|
||||||
```
|
```
|
||||||
directory.exclude.homeserever: true
|
|
||||||
|
### 3PID exclusion in search
|
||||||
|
You can configure if the 3PID should also be included when doing a directory search.
|
||||||
|
By default, a search is performed on the 3PIDs. If you would like to not include them:
|
||||||
|
```yaml
|
||||||
|
directory.exclude.threepid: true
|
||||||
```
|
```
|
72
docs/features/experimental/application-service.md
Normal file
72
docs/features/experimental/application-service.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Integration as an Application Service
|
||||||
|
**WARNING:** These features are currently highly experimental. They can be removed or modified without notice.
|
||||||
|
All the features requires a Homeserver capable of connecting Application Services.
|
||||||
|
|
||||||
|
## Email notification for Room invites by Matrix ID
|
||||||
|
This feature allows for users found in Identity stores to be instantly notified about Room Invites, regardless if their
|
||||||
|
account was already provisioned on the Homeserver.
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
- [Identity store(s)](../../stores/README.md) supporting the Profile feature
|
||||||
|
- At least one email entry in the identity store for each user that could be invited.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
In your mxisd config file:
|
||||||
|
```yaml
|
||||||
|
matrix:
|
||||||
|
listener:
|
||||||
|
url: '<URL TO THE CS API OF THE HOMESERVER>'
|
||||||
|
localpart: 'appservice-mxisd'
|
||||||
|
token:
|
||||||
|
hs: 'HS_TOKEN_CHANGE_ME'
|
||||||
|
|
||||||
|
synapseSql:
|
||||||
|
enabled: false ## Do not use this line if Synapse is used as an Identity Store
|
||||||
|
type: '<DB TYPE>'
|
||||||
|
connection: '<DB CONNECTION URL>'
|
||||||
|
```
|
||||||
|
|
||||||
|
The `synapseSql` section is used to retrieve display names which are not directly accessible in this mode.
|
||||||
|
For details about `type` and `connection`, see the [relevant documentation](../../stores/synapse.md).
|
||||||
|
If you do not configure it, some placeholders will not be available in the notification, like the Room name.
|
||||||
|
|
||||||
|
You can also change the default template of the notification using the `generic.matrixId` template option.
|
||||||
|
See [the Template generator documentation](../../threepids/notification/template-generator.md) for more info.
|
||||||
|
|
||||||
|
### Homeserver integration
|
||||||
|
#### Synapse
|
||||||
|
Create a new appservice registration file. Futher config will assume it is in `/etc/matrix-synapse/appservice-mxisd.yaml`
|
||||||
|
```yaml
|
||||||
|
id: "appservice-mxisd"
|
||||||
|
url: "http://127.0.0.1:8090"
|
||||||
|
as_token: "AS_TOKEN_CHANGE_ME"
|
||||||
|
hs_token: "HS_TOKEN_CHANGE_ME"
|
||||||
|
sender_localpart: "appservice-mxisd"
|
||||||
|
namespaces:
|
||||||
|
users:
|
||||||
|
- regex: "@*"
|
||||||
|
exclusive: false
|
||||||
|
aliases: []
|
||||||
|
rooms: []
|
||||||
|
```
|
||||||
|
`id`: An arbitrary unique string to identify the AS.
|
||||||
|
`url`: mxisd to reach mxisd. This ideally should be HTTP and not going through any reverse proxy.
|
||||||
|
`as_token`: Arbitrary value used by mxisd when talking to the HS. Not currently used.
|
||||||
|
`hs_token`: Arbitrary value used by synapse when talking to mxisd. Must match `token.hs` in mxisd config.
|
||||||
|
`sender_localpart`: Username for the mxisd itself on the HS. Default configuration should be kept.
|
||||||
|
`namespaces`: To be kept as is.
|
||||||
|
|
||||||
|
Edit your `homeserver.yaml` and add a new entry to the appservice config file, which should look something like this:
|
||||||
|
```yaml
|
||||||
|
app_service_config_files:
|
||||||
|
- '/etc/matrix-synapse/appservice-mxisd.yaml'
|
||||||
|
- ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart synapse when done to register mxisd.
|
||||||
|
|
||||||
|
#### Others
|
||||||
|
See your Homeserver documentation on how to integrate.
|
||||||
|
|
||||||
|
### Test
|
||||||
|
Invite a user which is part of your domain while an appropriate Identity store is used.
|
12
docs/features/experimental/profile.md
Normal file
12
docs/features/experimental/profile.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Profile enhancement
|
||||||
|
**WARNING**: Alpha feature, not officially supported. Do not use.
|
||||||
|
|
||||||
|
This feature allows to enhance a profile query with more info than just Matrix ID and Display name, allowing for custom
|
||||||
|
applications to retrieve custom data not currently provided by synapse, per example.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
### Reverse proxy
|
||||||
|
#### Apache
|
||||||
|
```apache
|
||||||
|
ProxyPassMatch "^/_matrix/client/r0/profile/([^/]+)$" "http://127.0.0.1:8090/_matrix/client/r0/profile/$1"
|
||||||
|
```
|
@@ -1,4 +1,15 @@
|
|||||||
# Identity service Federation
|
# Federation
|
||||||
|
Federation is the process by which domain owners can make compatible 3PIDs mapping auto-discoverable by looking for another
|
||||||
|
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.
|
||||||
|
On the other hand, Phone numbers cannot be resolved this way.
|
||||||
|
|
||||||
|
For 3PIDs which are not compatible with the DNS system, mxisd can be configured to talk to fallback Identity servers like
|
||||||
|
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.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
```
|
```
|
||||||
+-------------------+ +-------------> +----------+
|
+-------------------+ +-------------> +----------+
|
||||||
@@ -6,28 +17,33 @@
|
|||||||
| | | +------> +----------+
|
| | | +------> +----------+
|
||||||
| | | |
|
| | | |
|
||||||
| 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 |
|
|
||||||
+--------------------------+
|
|
||||||
```
|
```
|
||||||
To allow other federated Identity Server to reach yours, the same algorithm used for Homeservers takes place:
|
|
||||||
1. Check for the appropriate DNS SRV record
|
|
||||||
2. If not found, use the base domain
|
|
||||||
|
|
||||||
## Configuration
|
## Inbound
|
||||||
If your Identity Server public hostname does not match your Matrix domain, configure the following DNS SRV entry
|
If you would like to be reachable for lookups over federation, create the following DNS SRV entry and replace
|
||||||
and replace `matrix.example.com` by your Identity server public hostname - **Make sure to end with a final dot!**
|
`matrix.example.com` by your Identity server public hostname:
|
||||||
```
|
```
|
||||||
_matrix-identity._tcp.example.com. 3600 IN SRV 10 0 443 matrix.example.com.
|
_matrix-identity._tcp.example.com. 3600 IN SRV 10 0 443 matrix.example.com.
|
||||||
```
|
```
|
||||||
This would only apply for 3PID that are DNS-based, like e-mails. For anything else, like phone numbers, no federation
|
|
||||||
is currently possible.
|
|
||||||
|
|
||||||
The port must be HTTPS capable which is what you get in a regular setup with a reverse proxy from 443 to TCP 8090 of mxisd.
|
The port must be HTTPS capable which is what you get in a regular setup with a reverse proxy from 443 to TCP 8090 of mxisd.
|
||||||
|
|
||||||
|
## Outbound
|
||||||
|
If you would like to disable outbound federation and isolate your identity server from the rest of the Matrix network,
|
||||||
|
use the following mxisd configuration options:
|
||||||
|
```yaml
|
||||||
|
lookup.recursive.enabled: false
|
||||||
|
invite.resolution.recursive: false
|
||||||
|
session.policy.validation.forLocal.toRemote.enabled: false
|
||||||
|
session.policy.validation.forRemote.toRemote.enabled: false
|
||||||
|
```
|
||||||
|
|
||||||
|
There is currently no way to selectively disable federation towards specific servers, but this feature is planned.
|
||||||
|
@@ -1,9 +1,19 @@
|
|||||||
# Matrix Identity Service
|
# Identity
|
||||||
**WARNING**: This document is incomplete and can be missleading.
|
**WARNING**: This document is incomplete and can be missleading.
|
||||||
|
|
||||||
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).
|
||||||
|
|
||||||
## Invitation
|
## 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-matrix/mxisd/issues/76).
|
||||||
|
|
||||||
|
## Room Invitations
|
||||||
Resolution can be customized using the following configuration:
|
Resolution can be customized using the following configuration:
|
||||||
|
|
||||||
`invite.resolution.recursive`
|
`invite.resolution.recursive`
|
||||||
@@ -16,3 +26,6 @@ Resolution can be customized using the following configuration:
|
|||||||
`invite.resolution.timer`
|
`invite.resolution.timer`
|
||||||
- Default value: `1`
|
- Default value: `1`
|
||||||
- Description: How often, in minutes, mxisd should try to resolve pending invites.
|
- Description: How often, in minutes, mxisd should try to resolve pending invites.
|
||||||
|
|
||||||
|
## 3PID addition to user profile
|
||||||
|
See the [3PID session documents](../threepids/session)
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
# Profile enhancement
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Reverse proxy
|
|
||||||
|
|
||||||
#### Apache
|
|
||||||
```
|
|
||||||
ProxyPassMatch "^/_matrix/client/r0/profile/([^/]+)$" "http://127.0.0.1:8090/_matrix/client/r0/profile/$1"
|
|
||||||
ProxyPassMatch "^/_matrix/client/r0/profile/([^/]+)/(.+)" "http://127.0.0.1:8008/_matrix/client/r0/profile/$1/$2"
|
|
||||||
|
|
||||||
```
|
|
@@ -7,21 +7,20 @@
|
|||||||
6. [Next steps](#next-steps)
|
6. [Next steps](#next-steps)
|
||||||
|
|
||||||
Following these quick start instructions, you will have a basic setup that can perform recursive/federated lookups and
|
Following these quick start instructions, you will have a basic setup that can perform recursive/federated lookups and
|
||||||
talk to the central Matrix.org Identity service.
|
talk to the central Matrix.org Identity server.
|
||||||
This will be a good ground work for further integration with your existing Identity stores.
|
This will be a good ground work for further integration with features and your existing Identity stores.
|
||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
You will need:
|
You will need:
|
||||||
- Homeserver
|
- Working Homeserver, ideally with working federation
|
||||||
- Reverse proxy with regular TLS/SSL certificate (Let's encrypt) for your mxisd domain
|
- Reverse proxy with regular TLS/SSL certificate (Let's encrypt) for your mxisd domain
|
||||||
|
|
||||||
As synapse requires an HTTPS connection when talking to an Identity service, a reverse proxy is required as mxisd does
|
As synapse requires an HTTPS connection when talking to an Identity service, **a reverse proxy is required** as mxisd does
|
||||||
not support HTTPS listener at this time.
|
not support HTTPS listener at this time.
|
||||||
|
|
||||||
For maximum integration, it is best to have your Homeserver and mxisd reachable via the same hostname.
|
For maximum integration, it is best to have your Homeserver and mxisd reachable via the same hostname.
|
||||||
You can also use a dedicated domain for mxisd, but will not have access to some features.
|
|
||||||
|
|
||||||
Be aware of a [NAT/Reverse proxy gotcha](https://github.com/kamax-io/mxisd/wiki/Gotchas#nating) if you use the same
|
Be aware of a [NAT/Reverse proxy gotcha](https://github.com/kamax-matrix/mxisd/wiki/Gotchas#nating) if you use the same
|
||||||
hostname.
|
hostname.
|
||||||
|
|
||||||
The following Quick Start guide assumes you will host the Homeserver and mxisd under the same hostname.
|
The following Quick Start guide assumes you will host the Homeserver and mxisd under the same hostname.
|
||||||
@@ -30,23 +29,25 @@ If you would like a high-level view of the infrastructure and how each feature i
|
|||||||
|
|
||||||
## Install
|
## Install
|
||||||
Install via:
|
Install via:
|
||||||
- [Debian package](install/debian.md)
|
|
||||||
- [Docker image](install/docker.md)
|
- [Docker image](install/docker.md)
|
||||||
|
- [Debian package](install/debian.md)
|
||||||
|
- [ArchLinux](install/archlinux.md)
|
||||||
|
- [NixOS](install/nixos.md)
|
||||||
- [Sources](build.md)
|
- [Sources](build.md)
|
||||||
|
|
||||||
See the [Latest release](https://github.com/kamax-io/mxisd/releases/latest) for links to each.
|
See the [Latest release](https://github.com/kamax-matrix/mxisd/releases/latest) for links to each.
|
||||||
|
|
||||||
## Configure
|
## Configure
|
||||||
**NOTE**: please view the install instruction for your platform, as this step might be optional/handled for you.
|
**NOTE**: please view the install instruction for your platform, as this step might be optional or already handled for you.
|
||||||
|
|
||||||
Create/edit a minimal configuration (see installer doc for the location):
|
Create/edit a minimal configuration (see installer doc for the location):
|
||||||
```
|
```yaml
|
||||||
matrix.domain: 'MyMatrixDomain.org'
|
matrix.domain: 'example.org'
|
||||||
key.path: '/path/to/signing.key.file'
|
key.path: '/path/to/signing.key.file'
|
||||||
storage.provider.sqlite.database: '/path/to/mxisd.db'
|
storage.provider.sqlite.database: '/path/to/mxisd.db'
|
||||||
```
|
```
|
||||||
- `matrix.domain` should be set to your Homeserver domain
|
- `matrix.domain` should be set to your Homeserver domain (`server_name` in synapse configuration)
|
||||||
- `key.path` will store the signing keys, which must be kept safe!
|
- `key.path` will store the signing keys, which must be kept safe! If the file does not exist, keys will be generated for you.
|
||||||
- `storage.provider.sqlite.database` is the location of the SQLite Database file which will hold state (invites, etc.)
|
- `storage.provider.sqlite.database` is the location of the SQLite Database file which will hold state (invites, etc.)
|
||||||
|
|
||||||
If your HS/mxisd hostname is not the same as your Matrix domain, configure `server.name`.
|
If your HS/mxisd hostname is not the same as your Matrix domain, configure `server.name`.
|
||||||
@@ -59,20 +60,20 @@ For an overview of a typical mxisd infrastructure, see the [dedicated document](
|
|||||||
In the `VirtualHost` section handling the domain with SSL, add the following and replace `0.0.0.0` by the internal
|
In the `VirtualHost` section handling the domain with SSL, add the following and replace `0.0.0.0` by the internal
|
||||||
hostname/IP pointing to mxisd.
|
hostname/IP 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!**
|
||||||
```
|
```apache
|
||||||
ProxyPass /_matrix/identity/ http://0.0.0.0:8090/_matrix/identity/
|
ProxyPass /_matrix/identity http://0.0.0.0:8090/_matrix/identity
|
||||||
```
|
```
|
||||||
|
|
||||||
Typical configuration would look like:
|
Typical configuration would look like:
|
||||||
```
|
```apache
|
||||||
<VirtualHost *:443>
|
<VirtualHost *:443>
|
||||||
ServerName example.org
|
ServerName example.org
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
ProxyPreserveHost on
|
ProxyPreserveHost on
|
||||||
ProxyPass /_matrix/identity/ http://localhost:8090/_matrix/identity/
|
ProxyPass /_matrix/identity http://localhost:8090/_matrix/identity
|
||||||
ProxyPass /_matrix/ http://localhost:8008/_matrix/
|
ProxyPass /_matrix http://localhost:8008/_matrix
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -80,14 +81,14 @@ Typical configuration would look like:
|
|||||||
In the `server` section handling the domain with SSL, add the following and replace `0.0.0.0` with the internal
|
In the `server` section handling the domain with SSL, add the following and replace `0.0.0.0` with the internal
|
||||||
hostname/IP pointing to mxisd.
|
hostname/IP 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!**
|
||||||
```
|
```nginx
|
||||||
location /_matrix/identity {
|
location /_matrix/identity {
|
||||||
proxy_pass http://0.0.0.0:8090/_matrix/identity;
|
proxy_pass http://0.0.0.0:8090/_matrix/identity;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Typical configuration would look like:
|
Typical configuration would look like:
|
||||||
```
|
```nginx
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name example.org;
|
server_name example.org;
|
||||||
@@ -110,37 +111,32 @@ server {
|
|||||||
|
|
||||||
### Synapse
|
### Synapse
|
||||||
Add your mxisd domain into the `homeserver.yaml` at `trusted_third_party_id_servers` and restart synapse.
|
Add your mxisd domain into the `homeserver.yaml` at `trusted_third_party_id_servers` and restart synapse.
|
||||||
In a typical configuration, you would end up with something similair to:
|
In a typical configuration, you would end up with something similar to:
|
||||||
```
|
```yaml
|
||||||
trusted_third_party_id_servers:
|
trusted_third_party_id_servers:
|
||||||
- matrix.org
|
|
||||||
- vector.im
|
|
||||||
- example.org
|
- example.org
|
||||||
```
|
```
|
||||||
It is recommended to remove `matrix.org` and `vector.im` so only your own Identity server is authoritative for your HS.
|
It is recommended to remove `matrix.org` and `vector.im` (or any other default entry) from your configuration 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
|
**NOTE:** In case your homeserver has no working federation, step 5 will not happen. If step 4 took place, consider
|
||||||
the relevant hostname which you configured in your reverse proxy.
|
your installation validated.
|
||||||
Invite `mxisd-lookup-test@kamax.io` to a room, which should be turned into a Matrix invite to `@mxisd-lookup-test:kamax.io`.
|
|
||||||
**NOTE:** you might not see a Matrix suggestion for the e-mail address, which is normal. Still proceed with the invite.
|
1. Log in using your Matrix client and set `https://example.org` as your Identity server URL, replacing `example.org` by
|
||||||
|
the relevant hostname which you configured in your reverse proxy.
|
||||||
|
2. Create a new empty room. All further actions will take place in this room.
|
||||||
|
3. Invite `mxisd-federation-test@kamax.io`
|
||||||
|
4. The 3PID invite should be turned into a Matrix invite to `@mxisd-lookup-test:kamax.io`.
|
||||||
|
5. The invited test user will join the room, send a congratulation message and leave.
|
||||||
|
**NOTE:** You might not see a suggestion for the e-mail address, which is normal. Still proceed with the invite.
|
||||||
|
|
||||||
If it worked, it means you are up and running and can enjoy mxisd in its basic mode! Congratulations!
|
If it worked, it means you are up and running and can enjoy mxisd in its basic mode! Congratulations!
|
||||||
If it did not work, [get in touch](#support) and we'll do our best to get you started.
|
If it did not work, [get in touch](../README.md#support) and we'll do our best to get you started.
|
||||||
|
|
||||||
You can now integrate mxisd further with your infrastructure using the various [features](README.md) guides.
|
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
Once your mxisd server is up and running, here are the next steps to further enhance and integrate your installation:
|
Once your mxisd server is up and running, there are several ways you can enhance and integrate further with your
|
||||||
|
infrastructure:
|
||||||
|
|
||||||
Enable extra features:
|
- [Enable extra features](features/)
|
||||||
- [Federation](features/federation.md)
|
- [Use your own Identity stores](stores/README.md)
|
||||||
- [Authenticate with synapse](features/authentication.md), profile auto-provisioning if you wish
|
|
||||||
- [Directory search](features/directory-users.md)
|
|
||||||
|
|
||||||
Use your Identity stores:
|
|
||||||
- [LDAP / Samba / Active directory](backends/ldap.md)
|
|
||||||
- [SQL Database](backends/sql.md)
|
|
||||||
- [Website / Web service / Web app](backends/rest.md)
|
|
||||||
- [Google Firebase](backends/firebase.md)
|
|
||||||
- [Wordpress](backends/wordpress.md)
|
|
||||||
|
3
docs/install/archlinux.md
Normal file
3
docs/install/archlinux.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Arch Linux package
|
||||||
|
An Arch Linux package in the AUR repos is maintained by [r3pek](https://matrix.to/#/@r3pek:r3pek.org), a community member.
|
||||||
|
See https://aur.archlinux.org/packages/mxisd/
|
@@ -1,28 +1,31 @@
|
|||||||
# Debian package
|
# Debian package
|
||||||
|
## Requirements
|
||||||
|
- Any distribution that supports Java 8
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
1. Donwload the [latest release](https://github.com/kamax-io/mxisd/releases/latest)
|
1. Download the [latest release](https://github.com/kamax-matrix/mxisd/releases/latest)
|
||||||
2. Run:
|
2. Run:
|
||||||
```
|
```bash
|
||||||
dpkg -i /path/to/downloaded/mxisd.deb
|
dpkg -i /path/to/downloaded/mxisd.deb
|
||||||
```
|
```
|
||||||
## Files
|
## Files
|
||||||
| Location | Purpose |
|
| Location | Purpose |
|
||||||
|-----------------------------------|----------------------------------------------|
|
|-------------------------------------|----------------------------------------------|
|
||||||
| /etc/mxisd | Configuration directory |
|
| `/etc/mxisd` | Configuration directory |
|
||||||
| /etc/mxisd/mxisd.yaml | Main configuration file |
|
| `/etc/mxisd/mxisd.yaml` | Main configuration file |
|
||||||
| /etc/mxisd/signing.key | Default location for mxisd signing keys |
|
| `/etc/systemd/system/mxisd.service` | Systemd configuration file for mxisd service |
|
||||||
| /etc/systemd/system/mxisd.service | Systemd configuration file for mxisd service |
|
| `/usr/lib/mxisd` | Binaries |
|
||||||
| /usr/lib/mxisd | Binairies |
|
| `/var/lib/mxisd` | Data |
|
||||||
| /var/lib/mxisd | Data |
|
| `/var/lib/mxisd/signing.key` | Default location for mxisd signing keys |
|
||||||
|
|
||||||
## Control
|
## Control
|
||||||
Start mxisd using:
|
Start mxisd using:
|
||||||
```
|
```bash
|
||||||
sudo systemctl start mxisd
|
sudo systemctl start mxisd
|
||||||
```
|
```
|
||||||
|
|
||||||
Stop mxisd using:
|
Stop mxisd using:
|
||||||
```
|
```bash
|
||||||
sudo systemctl stop mxisd
|
sudo systemctl stop mxisd
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -35,5 +38,5 @@ tail -n 99 -f /var/log/syslog | grep mxisd
|
|||||||
```
|
```
|
||||||
- use Systemd's journal:
|
- use Systemd's journal:
|
||||||
```
|
```
|
||||||
journalctl -f n 99 -u mxisd
|
journalctl -f -n 99 -u mxisd
|
||||||
```
|
```
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# Docker
|
# Docker
|
||||||
## Fetch
|
## Fetch
|
||||||
Pull the latest stable image:
|
Pull the latest stable image:
|
||||||
```
|
```bash
|
||||||
docker pull kamax/mxisd
|
docker pull kamax/mxisd
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ Use the following command after adapting to your needs:
|
|||||||
- The `MATRIX_DOMAIN` environment variable to yours
|
- The `MATRIX_DOMAIN` environment variable to yours
|
||||||
- The volumes host paths
|
- The volumes host paths
|
||||||
|
|
||||||
```
|
```bash
|
||||||
docker run --rm -e MATRIX_DOMAIN=example.org -v /data/mxisd/etc:/etc/mxisd -v /data/mxisd/var:/var/mxisd -p 8090:8090 -t kamax/mxisd
|
docker run --rm -e MATRIX_DOMAIN=example.org -v /data/mxisd/etc:/etc/mxisd -v /data/mxisd/var:/var/mxisd -p 8090:8090 -t kamax/mxisd
|
||||||
```
|
```
|
||||||
|
|
||||||
|
8
docs/install/nixos.md
Normal file
8
docs/install/nixos.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# NixOS package
|
||||||
|
mxisd is available as a NixOS package in the official repos.
|
||||||
|
|
||||||
|
It is maintained by [maximilian](https://matrix.to/#/@maximilian:transformierende-gesellschaft.org), a community member.
|
||||||
|
|
||||||
|
Related resources:
|
||||||
|
- [NixOS](https://nixos.org/)
|
||||||
|
- [The module definition](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/mxisd.nix)
|
38
docs/install/source.md
Normal file
38
docs/install/source.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Install from sources
|
||||||
|
## Instructions
|
||||||
|
Follow the [build instructions](../build.md) then:
|
||||||
|
|
||||||
|
1. Prepare files and directories:
|
||||||
|
```bash
|
||||||
|
# Create a dedicated user
|
||||||
|
useradd -r mxisd
|
||||||
|
|
||||||
|
# Create bin directory
|
||||||
|
mkdir /opt/mxisd
|
||||||
|
|
||||||
|
# Create config directory and set ownership
|
||||||
|
mkdir -p /etc/opt/mxisd
|
||||||
|
chown -R mxisd /etc/opt/mxisd
|
||||||
|
|
||||||
|
# Create data directory and set ownership
|
||||||
|
mkdir -p /var/opt/mxisd
|
||||||
|
chown -R mxisd /var/opt/mxisd
|
||||||
|
|
||||||
|
# Copy <repo root>/build/libs/mxisd.jar to bin directory
|
||||||
|
cp ./build/libs/mxisd.jar /opt/mxisd/
|
||||||
|
chown mxisd /opt/mxisd/mxisd.jar
|
||||||
|
chmod a+x /opt/mxisd/mxisd.jar
|
||||||
|
|
||||||
|
# Create symlink for easy exec
|
||||||
|
ln -s /opt/mxisd/mxisd.jar /usr/bin/mxisd
|
||||||
|
```
|
||||||
|
2. Copy the sample config file `./application.example.yaml` to `/etc/opt/mxisd/mxisd.yaml`, edit to your needs
|
||||||
|
3. Copy `src/systemd/mxisd.service` to `/etc/systemd/system/` and edit if needed
|
||||||
|
4. Enable service for auto-startup
|
||||||
|
```bash
|
||||||
|
systemctl enable mxisd
|
||||||
|
```
|
||||||
|
5. Start mxisd
|
||||||
|
```bash
|
||||||
|
systemctl start mxisd
|
||||||
|
```
|
8
docs/stores/README.md
Normal file
8
docs/stores/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Identity Stores
|
||||||
|
- [Synapse](synapse.md) - Turn your SynapseDB into a self-contained Identity store
|
||||||
|
- [LDAP-based](ldap.md) - Any LDAP-based product like Active Directory, Samba, NetIQ, OpenLDAP
|
||||||
|
- [SQL Databases](sql.md) - Most common databases like MariaDB, MySQL, PostgreSQL, SQLite
|
||||||
|
- [Website / Web service / Web app](rest.md) - Arbitrary REST endpoints
|
||||||
|
- [Executables](exec.md) - Run arbitrary executables with configurable stdin, arguments, environment and stdout
|
||||||
|
- [Wordpress](wordpress.md) - Connect your Wordpress-powered website DB
|
||||||
|
- [Google Firebase](firebase.md) - Use your Firebase users (with experimental SSO support!)
|
470
docs/stores/exec.md
Normal file
470
docs/stores/exec.md
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
# Exec Identity Store
|
||||||
|
- [Features](#features)
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Global](#global)
|
||||||
|
- [Tokens](#tokens)
|
||||||
|
- [Executable](#executable)
|
||||||
|
- [Input](#input)
|
||||||
|
- [Output](#output)
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Per-Feature](#per-feature)
|
||||||
|
- [Authentication](#authentication)
|
||||||
|
- [Tokens](#tokens-1)
|
||||||
|
- [Input](#input-1)
|
||||||
|
- [Output](#output-1)
|
||||||
|
- [Directory](#directory)
|
||||||
|
- [Tokens](#tokens-2)
|
||||||
|
- [Input](#input-2)
|
||||||
|
- [Output](#output-2)
|
||||||
|
- [Identity](#identity)
|
||||||
|
- [Single Lookup](#single-lookup)
|
||||||
|
- [Tokens](#tokens-3)
|
||||||
|
- [Input](#input-3)
|
||||||
|
- [Output](#output-3)
|
||||||
|
- [Bulk Lookup](#bulk-lookup)
|
||||||
|
- [Tokens](#tokens-4)
|
||||||
|
- [Input](#input-4)
|
||||||
|
- [Output](#output-4)
|
||||||
|
- [Profile](#profile)
|
||||||
|
- [Tokens](#tokens-5)
|
||||||
|
- [Input](#input-5)
|
||||||
|
- [Output](#output-5)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported |
|
||||||
|
|-------------------------------------------------|-----------|
|
||||||
|
| [Authentication](../features/authentication.md) | Yes |
|
||||||
|
| [Directory](../features/directory.md) | Yes |
|
||||||
|
| [Identity](../features/identity.md) | Yes |
|
||||||
|
| [Profile](#profile) | Yes |
|
||||||
|
|
||||||
|
This Identity Store lets you run arbitrary commands to handle the various requests in each support feature.
|
||||||
|
It is the most versatile Identity store of mxisd, allowing you to connect any kind of logic with any executable/script.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Each request can be mapping to a fully customizable command configuration.
|
||||||
|
The various parameters can be provided via any combination of:
|
||||||
|
- [Standard Input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin))
|
||||||
|
- [Command-line arguments](https://en.wikipedia.org/wiki/Command-line_interface#Arguments)
|
||||||
|
- [Environment variables](https://en.wikipedia.org/wiki/Environment_variable)
|
||||||
|
|
||||||
|
Each of those supports a set of customizable token which will be replaced prior to running the command, allowing to
|
||||||
|
provide the input values in any number of ways.
|
||||||
|
|
||||||
|
Success and data will be provided via any combination of:
|
||||||
|
- [Exit status](https://en.wikipedia.org/wiki/Exit_status)
|
||||||
|
- [Standard Output](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout))
|
||||||
|
|
||||||
|
Each of those supports a set of configuration item to decide how to process the value and/or in which format.
|
||||||
|
|
||||||
|
All values, inputs and outputs are UTF-8 encoded.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
Each feature comes with a set of possible lookup/action which is mapped to a generic configuration item block.
|
||||||
|
We will use the term `Executable` for each lookup/action and `Processor` for each configuration block.
|
||||||
|
|
||||||
|
### Global
|
||||||
|
```yaml
|
||||||
|
exec.enabled: <boolean>
|
||||||
|
```
|
||||||
|
Enable/disable the Identity store at a global/default level. Each feature can still be individually enabled/disabled.
|
||||||
|
|
||||||
|
#### Tokens
|
||||||
|
The following options allow to globally set tokens for value replacement across all features and processors config.
|
||||||
|
Not all features use all tokens, and each feature might also have its own specific tokens. See each feature documentation.
|
||||||
|
|
||||||
|
They can be set within the following scope:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
exec.token.<token>: '<value>'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The following tokens and default values are available:
|
||||||
|
```yaml
|
||||||
|
localpart: '{localpart}'
|
||||||
|
```
|
||||||
|
Localpart of Matrix User IDs
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
domain: '{domain}'
|
||||||
|
```
|
||||||
|
Domain of Matrix User IDs
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
mxid: '{mxid}'
|
||||||
|
```
|
||||||
|
Full representation of Matrix User IDs
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
medium: '{medium}'
|
||||||
|
```
|
||||||
|
Medium of 3PIDs
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
address: '{address}'
|
||||||
|
```
|
||||||
|
Address of 3PIDs
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
type: '{type}'
|
||||||
|
```
|
||||||
|
Type of query
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
query: '{query}'
|
||||||
|
```
|
||||||
|
Query value
|
||||||
|
|
||||||
|
### Executable
|
||||||
|
*Executable*s have the following options:
|
||||||
|
```yaml
|
||||||
|
command: '/path/to/executableOrScript'
|
||||||
|
|
||||||
|
```
|
||||||
|
Set the executable (relative or absolute) path to be executed. If no command is given, the action will return a "neutral"
|
||||||
|
result if possible or be skipped altogether.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Command line arguments can be given via a list via both YAML formats:
|
||||||
|
```yaml
|
||||||
|
args:
|
||||||
|
- '-t'
|
||||||
|
- '{token}'
|
||||||
|
- '-v'
|
||||||
|
- 'value'
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```yaml
|
||||||
|
args: ['-t', '{token}', '-v', 'value]
|
||||||
|
```
|
||||||
|
Each argument will be processed for token replacement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Environment variables can be given as key/value pairs:
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
ENV_VAR_1: 'value'
|
||||||
|
ENV_VAR_2: '{token}'
|
||||||
|
```
|
||||||
|
Each variable value will be processed for token replacement.
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
Standard input can be configured in the namespaces `input` with:
|
||||||
|
- `type`: The format to use
|
||||||
|
- `template`: The full or partial template with tokens to be used when generating the input
|
||||||
|
|
||||||
|
Not all features and *Executable*s allow for a template to be provided.
|
||||||
|
Templates for listed-based input are not supported at this time.
|
||||||
|
Default templates may be provided per *Executable*.
|
||||||
|
|
||||||
|
The following types are available:
|
||||||
|
- `json`: Use JSON format, shared with the [REST Identity Store](rest.md)
|
||||||
|
- `plain`: Use a custom multi-lines, optionally tab-separated input
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
Standard output can be configured in the namespaces `output` with:
|
||||||
|
- `type`: The format to use
|
||||||
|
- `template`: The full or partial template with tokens to be used when processing the output
|
||||||
|
|
||||||
|
Not all features and *Executable*s allow for a template to be provided.
|
||||||
|
Templates for listed-based output are not supported at this time.
|
||||||
|
Default templates may be provided per *Executable*.
|
||||||
|
|
||||||
|
The following types are available:
|
||||||
|
- `json`: Use JSON format, shared with the [REST Identity Store](rest.md)
|
||||||
|
- `plain`: Use a custom multi-lines, optionally tab-separated output
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
#### Basic
|
||||||
|
```yaml
|
||||||
|
exec.auth.enabled: true
|
||||||
|
exec.auth.command: '/opt/mxisd-exec/auth.sh'
|
||||||
|
exec.auth.args: ['{localpart}']
|
||||||
|
exec.auth.input.type: 'plain'
|
||||||
|
exec.auth.input.template: '{password}'
|
||||||
|
exec.auth.env:
|
||||||
|
DOMAIN: '{domain}'
|
||||||
|
```
|
||||||
|
With Authentication enabled, run `/opt/mxisd-exec/auth.sh` when validating credentials, providing:
|
||||||
|
- A single command-line argument to provide the `localoart` as username
|
||||||
|
- A plain text string with the password token for standard input, which will be replaced by the password to check
|
||||||
|
- A single environment variable `DOMAIN` containing Matrix ID domain, if given
|
||||||
|
|
||||||
|
The command will use the default values for:
|
||||||
|
- Success exit status of `0`
|
||||||
|
- Failure exit status of `1`
|
||||||
|
- Any other exit status considered as error
|
||||||
|
- The standard output processing as not processed
|
||||||
|
|
||||||
|
#### Advanced
|
||||||
|
Given the fictional `placeholder` feature:
|
||||||
|
```yaml
|
||||||
|
exec.enabled: true
|
||||||
|
exec.token.mxid: '{matrixId}'
|
||||||
|
|
||||||
|
exec.placeholder.token.localpart: '{username}'
|
||||||
|
exec.placeholder.command: '/path/to/executable'
|
||||||
|
exec.placeholder.args:
|
||||||
|
- '-u'
|
||||||
|
- '{username}'
|
||||||
|
exec.placeholder.env:
|
||||||
|
MATRIX_DOMAIN: '{domain}'
|
||||||
|
MATRIX_USER_ID: '{matrixId}'
|
||||||
|
|
||||||
|
exec.placeholder.output.type: 'json'
|
||||||
|
exec.placeholder.exit.success: [0, 128]
|
||||||
|
exec.placeholder.exit.failure: [1, 129]
|
||||||
|
```
|
||||||
|
With:
|
||||||
|
- The Identity store enabled for all features
|
||||||
|
- A global specific token `{matrixId}` for Matrix User IDs, replacing the default `{mxid}`
|
||||||
|
|
||||||
|
Running `/path/to/executable` providing:
|
||||||
|
- A custom token for localpart, `{username}`, used as a 2nd command-line argument
|
||||||
|
- An extracted Matrix User ID `localpart` provided as the second command line argument, the first one being `-u`
|
||||||
|
- A password, the extracted Matrix `domain` and the full User ID as arbitrary environment variables, respectively
|
||||||
|
`PASSWORD`, `MATRIX_DOMAIN` and `MATRIX_USER_ID`
|
||||||
|
|
||||||
|
After execution:
|
||||||
|
- Process stdout as [JSON](https://en.wikipedia.org/wiki/JSON)
|
||||||
|
- Consider exit status `0` and `128` as success and try to process the stdout for data
|
||||||
|
- Consider exit status `1` and `129` as failure and try to process the stdout for error code and message
|
||||||
|
|
||||||
|
### Per Feature
|
||||||
|
See each dedicated [Feature](#features) section.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
The Authentication feature can be enabled/disabled using:
|
||||||
|
```yaml
|
||||||
|
exec.auth.enabled: <true/false>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This feature provides a single *Executable* under the namespace:
|
||||||
|
```yaml
|
||||||
|
exec.auth:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tokens
|
||||||
|
The following tokens/default values are specific to this feature:
|
||||||
|
```yaml
|
||||||
|
password: '{password}'
|
||||||
|
```
|
||||||
|
The provided password
|
||||||
|
|
||||||
|
### Input
|
||||||
|
Supported input types and default templates:
|
||||||
|
|
||||||
|
#### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
#### Plain (`plain`)
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
{localpart}
|
||||||
|
{domain}
|
||||||
|
{mxid}
|
||||||
|
{password}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output
|
||||||
|
Supported output types and default templates:
|
||||||
|
|
||||||
|
#### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
#### Plain (`plain`)
|
||||||
|
**NOTE:** This has limited support. Use the JSON type for full support.
|
||||||
|
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
[success status, true or 1 are interpreted as success]
|
||||||
|
[display name of the user]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory
|
||||||
|
The Directory feature can be enabled/disabled using:
|
||||||
|
```yaml
|
||||||
|
exec.directory.enabled: <true/false>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Two search types configuration namespace are available, using the same input/output formats and templates:
|
||||||
|
|
||||||
|
By name:
|
||||||
|
```yaml
|
||||||
|
exec.directory.search.byName:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
By 3PID:
|
||||||
|
```yaml
|
||||||
|
exec.directory.search.byThreepid:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Tokens
|
||||||
|
No specific tokens are available.
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
Supported input types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
[type of search, following the REST Identity store format]
|
||||||
|
[query string]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
Supported output types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
**Not supported at this time.** Use the JSON type.
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
The Identity feature can be enabled/disabled using:
|
||||||
|
```yaml
|
||||||
|
exec.identity.enabled: <true/false>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Single lookup
|
||||||
|
Configuration namespace:
|
||||||
|
```yaml
|
||||||
|
exec.identity.lookup.single:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Tokens
|
||||||
|
No specific tokens are available.
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
Supported input types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
{medium}
|
||||||
|
{address}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
Supported output types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
[User ID type, as documented in the REST Identity Store]
|
||||||
|
[User ID value]
|
||||||
|
```
|
||||||
|
|
||||||
|
The User ID type will default to `localpart` if:
|
||||||
|
- Only one line is returned
|
||||||
|
- The first line is empty
|
||||||
|
|
||||||
|
### Bulk lookup
|
||||||
|
Configuration namespace:
|
||||||
|
```yaml
|
||||||
|
exec.identity.lookup.bulk:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Tokens
|
||||||
|
No specific tokens are available.
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
Supported input types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
**NOTE:** Custom Templates are not supported.
|
||||||
|
|
||||||
|
Same as the [REST Identity Store](rest.md).
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
**Not supported at this time.** Use the JSON type.
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
Supported output types and default templates:
|
||||||
|
|
||||||
|
##### JSON (`json`)
|
||||||
|
**NOTE:** Custom Templates are not supported.
|
||||||
|
|
||||||
|
Same as the [REST Identity Store](rest.md).
|
||||||
|
|
||||||
|
##### Plain (`plain`)
|
||||||
|
**Not supported at this time.** Use the JSON type.
|
||||||
|
|
||||||
|
## Profile
|
||||||
|
The Profile feature can be enabled/disabled using:
|
||||||
|
```yaml
|
||||||
|
exec.profile.enabled: <true/false>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The following *Executable*s namespace are available, share the same input/output formats and templates:
|
||||||
|
|
||||||
|
Get Display name:
|
||||||
|
```yaml
|
||||||
|
exec.profile.displayName:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Get 3PIDs:
|
||||||
|
```yaml
|
||||||
|
exec.profile.threePid:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Get Roles:
|
||||||
|
```yaml
|
||||||
|
exec.profile.role:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Tokens
|
||||||
|
No specific tokens are available.
|
||||||
|
|
||||||
|
### Input
|
||||||
|
Supported input types and default templates:
|
||||||
|
|
||||||
|
#### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
#### Plain (`plain`)
|
||||||
|
Default template:
|
||||||
|
```
|
||||||
|
{localpart}
|
||||||
|
{domain}
|
||||||
|
{mxid}
|
||||||
|
```
|
||||||
|
### Output
|
||||||
|
Supported output types and default templates:
|
||||||
|
|
||||||
|
#### JSON (`json`)
|
||||||
|
Same as the [REST Identity Store](rest.md);
|
||||||
|
|
||||||
|
#### Plain (`plain`)
|
||||||
|
**Not supported at this time.** Use the JSON type.
|
53
docs/stores/firebase.md
Normal file
53
docs/stores/firebase.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Google Firebase Identity store
|
||||||
|
https://firebase.google.com/
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported? |
|
||||||
|
|----------------|------------|
|
||||||
|
| Authentication | Yes |
|
||||||
|
| Directory | No |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | No |
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
This backend requires a suitable Matrix client capable of performing Firebase authentication and passing the following
|
||||||
|
information:
|
||||||
|
- Firebase User ID as Matrix username
|
||||||
|
- Firebase token as Matrix password
|
||||||
|
|
||||||
|
If your client is Riot, you will need a custom version.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
```yaml
|
||||||
|
firebase.enabled: <boolean>
|
||||||
|
```
|
||||||
|
Enable/disable this identity store.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
firebase.enabled: <boolean>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
firebase.credentials: <string>
|
||||||
|
```
|
||||||
|
Path to the credentials file provided by Google Firebase to use with an external app.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
firebase.credentials: '/path/to/firebase/credentials.json'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
firebase.database: <string>
|
||||||
|
```
|
||||||
|
URL to your Firebase database.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
firebase.database: 'https://my-project.firebaseio.com/'
|
||||||
|
```
|
121
docs/stores/ldap.md
Normal file
121
docs/stores/ldap.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# LDAP Identity store
|
||||||
|
## Supported products:
|
||||||
|
- Samba
|
||||||
|
- Active Directory
|
||||||
|
- OpenLDAP
|
||||||
|
- NetIQ eDirectory
|
||||||
|
|
||||||
|
For NetIQ, replace all the `ldap` prefix in the configuration by `netiq`.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported? |
|
||||||
|
|----------------|------------|
|
||||||
|
| Authentication | Yes |
|
||||||
|
| Directory | Yes |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | Yes |
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
### Base
|
||||||
|
To use your LDAP backend, add the bare minimum configuration in mxisd config file:
|
||||||
|
```yaml
|
||||||
|
ldap.enabled: true
|
||||||
|
ldap.connection.host: 'ldapHostnameOrIp'
|
||||||
|
ldap.connection.port: 389
|
||||||
|
ldap.connection.bindDn: 'CN=My Mxisd User,OU=Users,DC=example,DC=org'
|
||||||
|
ldap.connection.bindPassword: 'TheUserPassword'
|
||||||
|
ldap.connection.baseDn: 'OU=Users,DC=example,DC=org'
|
||||||
|
```
|
||||||
|
These are standard LDAP connection configuration. mxisd will try to connect on port default port 389 without encryption.
|
||||||
|
|
||||||
|
### TLS/SSL connection
|
||||||
|
If you would like to use a TLS/SSL connection, use the following configuration options (STARTLS not supported):
|
||||||
|
```yaml
|
||||||
|
ldap.connection.tls: true
|
||||||
|
ldap.connection.port: 12345
|
||||||
|
```
|
||||||
|
|
||||||
|
### Filter results
|
||||||
|
You can also set a default global filter on any LDAP queries:
|
||||||
|
```yaml
|
||||||
|
ldap.filter: '(memberOf=CN=My Matrix Users,OU=Groups,DC=example,DC=org)'
|
||||||
|
```
|
||||||
|
This example would only return users part of the group called `My Matrix Users`.
|
||||||
|
This can be overwritten or append in each specific flow describe below.
|
||||||
|
|
||||||
|
For supported syntax, see the [LDAP library documentation](http://directory.apache.org/api/user-guide/2.3-searching.html#filter).
|
||||||
|
|
||||||
|
### Attribute mapping
|
||||||
|
LDAP features are based on mapping LDAP attributes to Matrix concepts, like a Matrix ID, its localpart, the user display
|
||||||
|
name, their email(s) and/or phone number(s).
|
||||||
|
|
||||||
|
Default attributes are well suited for Active Directory/Samba. In case you are using a native LDAP backend, you will
|
||||||
|
most certainly configure those mappings.
|
||||||
|
|
||||||
|
#### User ID
|
||||||
|
`ldap.attribute.uid.type`: How to process the User ID (UID) attribute:
|
||||||
|
- `uid` will consider the value as the [Localpart](https://matrix.org/docs/spec/intro.html#user-identifiers)
|
||||||
|
- `mxid` will consider the value as a complete [Matrix ID](https://matrix.org/docs/spec/intro.html#user-identifiers)
|
||||||
|
|
||||||
|
`ldap.attribute.uid.value`: Attribute to use to set the User ID value.
|
||||||
|
|
||||||
|
The following example would set the `sAMAccountName` attribute as a Matrix User ID localpart:
|
||||||
|
```yaml
|
||||||
|
ldap.attribute.uid.type: 'uid'
|
||||||
|
ldap.attribute.uid.value: 'sAMAccountName'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Display name
|
||||||
|
Use `ldap.attribute.name`.
|
||||||
|
|
||||||
|
The following example would set the display name to the value of the `cn` attribute:
|
||||||
|
```yaml
|
||||||
|
ldap.attribute.name: 'cn'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3PIDs
|
||||||
|
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:
|
||||||
|
```yaml
|
||||||
|
ldap.attribute.threepid.email:
|
||||||
|
- 'mail'
|
||||||
|
- 'otherMailAttribute'
|
||||||
|
|
||||||
|
ldap.attribute.threepid.msisdn:
|
||||||
|
- 'phone'
|
||||||
|
- 'otherPhoneAttribute'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
### Identity
|
||||||
|
Identity features (related to 3PID invites or searches) are enabled and configured using default values and no specific
|
||||||
|
configuration item is needed to get started.
|
||||||
|
|
||||||
|
#### Configuration
|
||||||
|
- `ldap.identity.filter`: Specific user filter applied during identity search. Global filter is used if blank/not set.
|
||||||
|
- `ldap.identity.medium`: Namespace to overwrite generated queries from the list of attributes for each 3PID medium.
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
No further configuration is needed to use the Authentication feature with LDAP once globally enabled and configured.
|
||||||
|
|
||||||
|
Profile auto-fill is enabled by default. It will use the `ldap.attribute.name` and `ldap.attribute.threepid` configuration
|
||||||
|
options to get a lit of attributes to be used to build the user profile to pass on to synapse during authentication.
|
||||||
|
|
||||||
|
#### Configuration
|
||||||
|
- `ldap.auth.filter`: Specific user filter applied during identity search. Global filter is used if blank/not set.
|
||||||
|
|
||||||
|
### Directory
|
||||||
|
No further configuration is needed to use the Directory feature with LDAP once globally enabled and configured.
|
||||||
|
|
||||||
|
#### Configuration
|
||||||
|
To set a specific filter applied during directory search, use `ldap.directory.filter`
|
||||||
|
|
||||||
|
If you would like to use extra attributes in search that are not 3PIDs, like nicknames, group names, employee number:
|
||||||
|
```yaml
|
||||||
|
ldap.directory.attribute.other:
|
||||||
|
- 'myNicknameAttribute'
|
||||||
|
- 'memberOf'
|
||||||
|
- 'employeeNumberAttribute'
|
||||||
|
```
|
@@ -1,27 +1,29 @@
|
|||||||
# REST backend
|
# REST Identity store
|
||||||
The REST backend allows you to query identity data in existing webapps, like:
|
The REST backend allows you to query identity data in existing webapps, like:
|
||||||
- Forums (phpBB, Discourse, etc.)
|
- Forums (phpBB, Discourse, etc.)
|
||||||
- Custom Identity stores (Keycloak, ...)
|
- Custom Identity stores (Keycloak, ...)
|
||||||
- CRMs (Wordpress, ...)
|
- CRMs (Wordpress, ...)
|
||||||
- self-hosted clouds (Nextcloud, ownCloud, ...)
|
- self-hosted clouds (Nextcloud, ownCloud, ...)
|
||||||
|
|
||||||
It supports the following mxisd flows:
|
|
||||||
- [Authentication](#authentication)
|
|
||||||
- [Directory](#directory)
|
|
||||||
- [Identity](#identity)
|
|
||||||
|
|
||||||
To integrate this backend with your webapp, you will need to implement three specific REST endpoints detailed below.
|
To integrate this backend with your webapp, you will need to implement three specific REST endpoints detailed below.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported? |
|
||||||
|
|----------------|------------|
|
||||||
|
| Authentication | Yes |
|
||||||
|
| Directory | Yes |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | No |
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
| Key | Default | Description |
|
| Key | Default | Description |
|
||||||
---------------------------------|----------------------------------------------|------------------------------------------------------|
|
|----------------------------------|------------------------------------------------|------------------------------------------------------|
|
||||||
| rest.enabled | false | Globally enable/disable the REST backend |
|
| `rest.enabled` | `false` | Globally enable/disable the REST backend |
|
||||||
| rest.host | *empty* | Default base URL to use for the different endpoints. |
|
| `rest.host` | *None* | Default base URL to use for the different endpoints. |
|
||||||
| rest.endpoints.auth | /_mxisd/backend/api/v1/auth/login | Validate credentials and get user profile |
|
| `rest.endpoints.auth` | `/_mxisd/backend/api/v1/auth/login` | Validate credentials and get user profile |
|
||||||
| rest.endpoints.directory | /_mxisd/backend/api/v1/directory/user/search | Search for users by arbitrary input |
|
| `rest.endpoints.directory` | `/_mxisd/backend/api/v1/directory/user/search` | Search for users by arbitrary input |
|
||||||
| rest.endpoints.identity.single | /_mxisd/backend/api/v1/identity/single | Endpoint to query a single 3PID |
|
| `rest.endpoints.identity.single` | `/_mxisd/backend/api/v1/identity/single` | Endpoint to query a single 3PID |
|
||||||
| rest.endpoints.identity.bulk | /_mxisd/backend/api/v1/identity/bulk | Endpoint to query a list of 3PID |
|
| `rest.endpoints.identity.bulk` | `/_mxisd/backend/api/v1/identity/bulk` | Endpoint to query a list of 3PID |
|
||||||
|
|
||||||
Endpoint values can handle two formats:
|
Endpoint values can handle two formats:
|
||||||
- URL Path starting with `/` that gets happened to the `rest.host`
|
- URL Path starting with `/` that gets happened to the `rest.host`
|
||||||
@@ -35,7 +37,7 @@ HTTP method: `POST`
|
|||||||
Content-type: JSON UTF-8
|
Content-type: JSON UTF-8
|
||||||
|
|
||||||
#### Request Body
|
#### Request Body
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"auth": {
|
"auth": {
|
||||||
"mxid": "@john.doe:example.org",
|
"mxid": "@john.doe:example.org",
|
||||||
@@ -48,7 +50,7 @@ Content-type: JSON UTF-8
|
|||||||
|
|
||||||
#### Response Body
|
#### Response Body
|
||||||
If the authentication fails:
|
If the authentication fails:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"auth": {
|
"auth": {
|
||||||
"success": false
|
"success": false
|
||||||
@@ -59,7 +61,7 @@ If the authentication fails:
|
|||||||
If the authentication succeed:
|
If the authentication succeed:
|
||||||
- `auth.id` supported values: `localpart`, `mxid`
|
- `auth.id` supported values: `localpart`, `mxid`
|
||||||
- `auth.profile` and any sub-member are all optional
|
- `auth.profile` and any sub-member are all optional
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"auth": {
|
"auth": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -89,7 +91,7 @@ HTTP method: `POST`
|
|||||||
Content-type: JSON UTF-8
|
Content-type: JSON UTF-8
|
||||||
|
|
||||||
#### Request Body
|
#### Request Body
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"by": "<search type>",
|
"by": "<search type>",
|
||||||
"search_term": "doe"
|
"search_term": "doe"
|
||||||
@@ -101,7 +103,7 @@ Content-type: JSON UTF-8
|
|||||||
|
|
||||||
#### Response Body:
|
#### Response Body:
|
||||||
If users found:
|
If users found:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"limited": false,
|
"limited": false,
|
||||||
"results": [
|
"results": [
|
||||||
@@ -118,7 +120,7 @@ If users found:
|
|||||||
```
|
```
|
||||||
|
|
||||||
If no user found:
|
If no user found:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"limited": false,
|
"limited": false,
|
||||||
"results": []
|
"results": []
|
||||||
@@ -131,7 +133,7 @@ HTTP method: `POST`
|
|||||||
Content-type: JSON UTF-8
|
Content-type: JSON UTF-8
|
||||||
|
|
||||||
#### Request Body
|
#### Request Body
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"lookup": {
|
"lookup": {
|
||||||
"medium": "email",
|
"medium": "email",
|
||||||
@@ -143,7 +145,7 @@ Content-type: JSON UTF-8
|
|||||||
#### Response Body
|
#### Response Body
|
||||||
If a match was found:
|
If a match was found:
|
||||||
- `lookup.id.type` supported values: `localpart`, `mxid`
|
- `lookup.id.type` supported values: `localpart`, `mxid`
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"lookup": {
|
"lookup": {
|
||||||
"medium": "email",
|
"medium": "email",
|
||||||
@@ -157,7 +159,7 @@ If a match was found:
|
|||||||
```
|
```
|
||||||
|
|
||||||
If no match was found:
|
If no match was found:
|
||||||
```
|
```json
|
||||||
{}
|
{}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -166,7 +168,7 @@ HTTP method: `POST`
|
|||||||
Content-type: JSON UTF-8
|
Content-type: JSON UTF-8
|
||||||
|
|
||||||
#### Request Body
|
#### Request Body
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"lookup": [
|
"lookup": [
|
||||||
{
|
{
|
||||||
@@ -184,7 +186,7 @@ Content-type: JSON UTF-8
|
|||||||
#### Response Body
|
#### Response Body
|
||||||
For all entries where a match was found:
|
For all entries where a match was found:
|
||||||
- `lookup[].id.type` supported values: `localpart`, `mxid`
|
- `lookup[].id.type` supported values: `localpart`, `mxid`
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"lookup": [
|
"lookup": [
|
||||||
{
|
{
|
||||||
@@ -208,7 +210,7 @@ For all entries where a match was found:
|
|||||||
```
|
```
|
||||||
|
|
||||||
If no match was found:
|
If no match was found:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"lookup": []
|
"lookup": []
|
||||||
}
|
}
|
99
docs/stores/sql.md
Normal file
99
docs/stores/sql.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# SQL Identity store
|
||||||
|
## Supported Databases
|
||||||
|
- PostgreSQL
|
||||||
|
- MariaDB
|
||||||
|
- MySQL
|
||||||
|
- SQLite
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported? |
|
||||||
|
|----------------|------------|
|
||||||
|
| Authentication | No |
|
||||||
|
| Directory | Yes |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | Yes |
|
||||||
|
|
||||||
|
Due to the implementation complexity of supporting arbitrary hashing/encoding mechanisms or auth flow, Authentication
|
||||||
|
will be out of scope of SQL Identity stores and should be done via one of the other identity stores, typically
|
||||||
|
the [REST Identity store](rest.md).
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
### Basic
|
||||||
|
```yaml
|
||||||
|
sql.enabled: <boolean>
|
||||||
|
```
|
||||||
|
Enable/disable the identity store
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sql.type: <string>
|
||||||
|
```
|
||||||
|
Set the SQL backend to use:
|
||||||
|
- `sqlite`
|
||||||
|
- `postgresql`
|
||||||
|
- `mariadb`
|
||||||
|
- `mysql`
|
||||||
|
|
||||||
|
### Connection
|
||||||
|
#### SQLite
|
||||||
|
```yaml
|
||||||
|
sql.connection: <string>
|
||||||
|
```
|
||||||
|
Set the value to the absolute path to the Synapse SQLite DB file.
|
||||||
|
Example: `/path/to/sqlite/file.db`
|
||||||
|
|
||||||
|
#### Others
|
||||||
|
```yaml
|
||||||
|
sql.connection: //<HOST[:PORT]/DB?user=USER&password=PASS
|
||||||
|
```
|
||||||
|
Set the connection info for the database by replacing the following values:
|
||||||
|
- `HOST`: Hostname of the SQL server
|
||||||
|
- `PORT`: Optional port value, if not default
|
||||||
|
- `DB`: Database name
|
||||||
|
- `USER`: Username for the connection
|
||||||
|
- `PASS`: Password for the connection
|
||||||
|
|
||||||
|
This follow the JDBC URI syntax. See [official website](https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html#db_connection_url).
|
||||||
|
|
||||||
|
### Directory
|
||||||
|
```yaml
|
||||||
|
sql.directory.enabled: false
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sql.directory.query:
|
||||||
|
name:
|
||||||
|
type: <string>
|
||||||
|
value: <string>
|
||||||
|
threepid:
|
||||||
|
type: <string>
|
||||||
|
value: <string>
|
||||||
|
```
|
||||||
|
For each query, `type` can be used to tell mxisd how to process the ID column:
|
||||||
|
- `localpart` will append the `matrix.domain` to it
|
||||||
|
- `mxid` will use the ID as-is. If it is not a valid Matrix ID, the search will fail.
|
||||||
|
|
||||||
|
`value` is the SQL query and must return two columns:
|
||||||
|
- The first being the User ID
|
||||||
|
- The second being its display name
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
sql.directory.query:
|
||||||
|
name:
|
||||||
|
type: 'localpart'
|
||||||
|
value: 'SELECT idColumn, displayNameColumn FROM table WHERE displayNameColumn LIKE ?'
|
||||||
|
threepid:
|
||||||
|
type: 'localpart'
|
||||||
|
value: 'SELECT idColumn, displayNameColumn FROM table WHERE threepidColumn LIKE ?'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Identity
|
||||||
|
```yaml
|
||||||
|
sql.identity.type: <string>
|
||||||
|
sql.identity.query: <string>
|
||||||
|
```
|
49
docs/stores/synapse.md
Normal file
49
docs/stores/synapse.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Synapse Identity Store
|
||||||
|
Synapse's Database itself can be used as an Identity store.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
| Name | Supported? |
|
||||||
|
|----------------|------------|
|
||||||
|
| Authentication | No |
|
||||||
|
| Directory | Yes |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | Yes |
|
||||||
|
|
||||||
|
Authentication is done by Synapse itself.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
### Basic
|
||||||
|
```yaml
|
||||||
|
synapseSql.enabled: <boolean>
|
||||||
|
```
|
||||||
|
Enable/disable the identity store
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
synapseSql.type: <string>
|
||||||
|
```
|
||||||
|
Set the SQL backend to use which is configured in synapse:
|
||||||
|
- `sqlite`
|
||||||
|
- `postgresql`
|
||||||
|
|
||||||
|
### SQLite
|
||||||
|
```yaml
|
||||||
|
synapseSql.connection: <string>
|
||||||
|
```
|
||||||
|
Set the value to the absolute path to the Synapse SQLite DB file.
|
||||||
|
Example: `/path/to/synapse/sqliteFile.db`
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
```yaml
|
||||||
|
synapseSql.connection: //<HOST[:PORT]/DB?user=USER&password=PASS
|
||||||
|
```
|
||||||
|
Set the connection info for the database by replacing the following values:
|
||||||
|
- `HOST`: Hostname of the SQL server
|
||||||
|
- `PORT`: Optional port value, if not default
|
||||||
|
- `DB`: Database name
|
||||||
|
- `USER`: Username for the connection
|
||||||
|
- `PASS`: Password for the connection
|
||||||
|
|
||||||
|
### Query customization
|
||||||
|
See the [SQL Identity store](sql.md)
|
@@ -1,13 +1,16 @@
|
|||||||
# Wordpress
|
# Wordpress Identity store
|
||||||
This Identity store allows you to use user accounts registered on your Wordpress setup.
|
This Identity store allows you to use user accounts registered on your Wordpress setup.
|
||||||
Two types of connections are required for full support:
|
Two types of connections are required for full support:
|
||||||
- [REST API](https://developer.wordpress.org/rest-api/) with JWT authentication
|
- [REST API](https://developer.wordpress.org/rest-api/) with JWT authentication
|
||||||
- Direct SQL access
|
- Direct SQL access
|
||||||
|
|
||||||
This Identity store supports the following features:
|
## Features
|
||||||
- [Authentication](../features/authentication.md)
|
| Name | Supported? |
|
||||||
- [Directory](../features/directory-users.md)
|
|----------------|------------|
|
||||||
- [Identity](../features/identity.md)
|
| Authentication | Yes |
|
||||||
|
| Directory | Yes |
|
||||||
|
| Identity | Yes |
|
||||||
|
| Profile | No |
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- [Wordpress](https://wordpress.org/download/) >= 4.4
|
- [Wordpress](https://wordpress.org/download/) >= 4.4
|
||||||
@@ -19,7 +22,7 @@ This Identity store supports the following features:
|
|||||||
### Wordpress
|
### Wordpress
|
||||||
#### JWT Auth
|
#### JWT Auth
|
||||||
Set a JWT secret into `wp-config.php` like so:
|
Set a JWT secret into `wp-config.php` like so:
|
||||||
```
|
```php
|
||||||
define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');
|
define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');
|
||||||
```
|
```
|
||||||
`your-top-secret-key` should be set to a randomly generated value which is kept secret.
|
`your-top-secret-key` should be set to a randomly generated value which is kept secret.
|
||||||
@@ -30,26 +33,34 @@ If this is not the case for your installation, the mxisd URL will need to be app
|
|||||||
|
|
||||||
### mxisd
|
### mxisd
|
||||||
Enable in the configuration:
|
Enable in the configuration:
|
||||||
```
|
```yaml
|
||||||
wordpress.enabled: true
|
wordpress.enabled: true
|
||||||
```
|
```
|
||||||
Configure the URL to your Wordpress installation - see above about added `/index.php`:
|
Configure the URL to your Wordpress installation - see above about added `/index.php`:
|
||||||
```
|
```yaml
|
||||||
wordpress.rest.base: 'http://localhost:8080'
|
wordpress.rest.base: 'http://localhost:8080'
|
||||||
```
|
```
|
||||||
Configure the SQL connection to your Wordpress database:
|
Configure the SQL connection to your Wordpress database:
|
||||||
```
|
```yaml
|
||||||
wordpress.sql.connection: '//127.0.0.1/wordpress?user=root&password=example'
|
wordpress.sql.connection: '//127.0.0.1/wordpress?user=root&password=example'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
By default, MySQL database is expected. If you use another database, use:
|
By default, MySQL database is expected. If you use another database, use:
|
||||||
```
|
```yaml
|
||||||
wordpress.sql.type: 'jdbc-scheme'
|
wordpress.sql.type: <string>
|
||||||
```
|
```
|
||||||
With possible values:
|
With possible values:
|
||||||
- `mysql`
|
- `mysql`
|
||||||
- `mariadb`
|
- `mariadb`
|
||||||
- `postgresql`
|
- `postgresql`
|
||||||
- `sqlite`
|
- `sqlite`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
To configure the tables prefix for default queries, in case a custom value was set during Wordpress install:
|
||||||
|
```yaml
|
||||||
|
wordpress.sql.tablePrefix: <string>
|
||||||
|
```
|
||||||
|
By default, the value is set to `wp_`.
|
@@ -1,19 +1,19 @@
|
|||||||
# Email notifications - SMTP connector
|
# Email notifications - SMTP connector
|
||||||
|
Enabled by default.
|
||||||
|
|
||||||
Connector ID: `smtp`
|
Connector ID: `smtp`
|
||||||
|
|
||||||
Example configuration:
|
## Configuration
|
||||||
```
|
```yaml
|
||||||
threepid:
|
threepid.medium.email:
|
||||||
medium:
|
identity:
|
||||||
email:
|
from: 'identityServerEmail@example.org'
|
||||||
identity:
|
name: 'My Identity Server'
|
||||||
from: 'identityServerEmail@example.org'
|
connectors:
|
||||||
name: 'My Identity Server'
|
smtp:
|
||||||
connectors:
|
host: 'smtpHostname'
|
||||||
smtp:
|
port: 587
|
||||||
host: 'smtpHostname'
|
tls: 1 # 0 = no STARTLS, 1 = try, 2 = force
|
||||||
port: 587
|
login: 'smtpLogin'
|
||||||
tls: 1 # 0 = no STARTLS, 1 = try, 2 = force
|
password: 'smtpPassword'
|
||||||
login: 'smtpLogin'
|
|
||||||
password: 'smtpPassword'
|
|
||||||
```
|
```
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
# SMS notifications - Twilio connector
|
# SMS notifications - Twilio connector
|
||||||
|
Enabled by default.
|
||||||
|
|
||||||
Connector ID: `twilio`
|
Connector ID: `twilio`
|
||||||
|
|
||||||
Example configuration:
|
## Configuration
|
||||||
```
|
```yaml
|
||||||
threepid:
|
threepid.medium.msisdn.connectors.twilio.accountSid: 'myAccountSid'
|
||||||
medium:
|
threepid.medium.msisdn.connectors.twilio.authToken: 'myAuthToken'
|
||||||
msisdn:
|
threepid.medium.msisdn.connectors.twilio.number: '+123456789'
|
||||||
connectors:
|
|
||||||
twilio:
|
|
||||||
accountSid: 'myAccountSid'
|
|
||||||
authToken: 'myAuthToken'
|
|
||||||
number: '+123456789'
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
37
docs/threepids/notification/basic-handler.md
Normal file
37
docs/threepids/notification/basic-handler.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Basic Notification handler
|
||||||
|
Basic notification handler which uses two components:
|
||||||
|
- Content generator, to produce the notifications
|
||||||
|
- Connectors to send the notification content
|
||||||
|
|
||||||
|
This handler can be used with the 3PID types:
|
||||||
|
- `email`
|
||||||
|
- `msisdn` (Phone numbers)
|
||||||
|
|
||||||
|
## Generators
|
||||||
|
- [Template](template-generator.md)
|
||||||
|
## Connectors
|
||||||
|
- Email
|
||||||
|
- [SMTP](../medium/email/smtp-connector.md)
|
||||||
|
- SMS
|
||||||
|
- [Twilio](../medium/msisdn/twilio-connector.md)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
Enabled by default or with:
|
||||||
|
```yaml
|
||||||
|
notification.handler.email: 'raw'
|
||||||
|
```
|
||||||
|
|
||||||
|
**WARNING:** Will be consolidated soon, prone to breaking changes.
|
||||||
|
Structure and default values:
|
||||||
|
```yaml
|
||||||
|
threepid.medium:
|
||||||
|
email:
|
||||||
|
identity:
|
||||||
|
from: ''
|
||||||
|
name: ''
|
||||||
|
connector: 'smtp'
|
||||||
|
generator: 'template'
|
||||||
|
msisdn:
|
||||||
|
connector: 'twilio'
|
||||||
|
generator: 'template'
|
||||||
|
```
|
7
docs/threepids/notification/sendgrid-handler.md
Normal file
7
docs/threepids/notification/sendgrid-handler.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# SendGrid Notification handler
|
||||||
|
To be completed. See [raw possible configuration items](https://github.com/kamax-matrix/mxisd/blob/master/src/main/resources/application.yaml#L172).
|
||||||
|
|
||||||
|
Enabled with:
|
||||||
|
```yaml
|
||||||
|
notification.handler.email: 'sendgrid'
|
||||||
|
```
|
@@ -10,17 +10,17 @@ placeholders and also have their own individual set of placeholders.
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
To configure paths to the various templates:
|
To configure paths to the various templates:
|
||||||
```
|
```yaml
|
||||||
threepid:
|
threepid.medium.<YOUR 3PID MEDIUM HERE>:
|
||||||
medium:
|
generators:
|
||||||
<YOUR 3PID MEDIUM HERE>:
|
template:
|
||||||
generators:
|
invite: '/path/to/invite-template.eml'
|
||||||
template:
|
session:
|
||||||
invite: '/path/to/invite-template.eml'
|
validation:
|
||||||
session:
|
local: '/path/to/validate-local-template.eml'
|
||||||
validation:
|
remote: 'path/to/validate-remote-template.eml'
|
||||||
local: '/path/to/validate-local-template.eml'
|
generic:
|
||||||
remote: 'path/to/validate-remote-template.eml'
|
matrixId: '/path/to/mxid-invite-template.eml'
|
||||||
```
|
```
|
||||||
The `template` generator is usually the default, so no further configuration is needed.
|
The `template` generator is usually the default, so no further configuration is needed.
|
||||||
|
|
@@ -1,66 +0,0 @@
|
|||||||
# Basic Notification handler
|
|
||||||
Basic notification handler which uses two components:
|
|
||||||
- Content generator, to produce the notifications
|
|
||||||
- Connectors to send the notification content
|
|
||||||
|
|
||||||
This handler can be used with the 3PID types:
|
|
||||||
- `email`
|
|
||||||
- `msisdn` (Phone numbers)
|
|
||||||
|
|
||||||
## Generators
|
|
||||||
- [Template](template-generator.md)
|
|
||||||
## Connectors
|
|
||||||
- Email
|
|
||||||
- [SMTP](../medium/email/smtp-connector.md)
|
|
||||||
- SMS
|
|
||||||
- [Twilio](../medium/msisdn/twilio-connector.md)
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
Enabled by default or with:
|
|
||||||
```
|
|
||||||
notification:
|
|
||||||
handler:
|
|
||||||
email: 'raw'
|
|
||||||
```
|
|
||||||
|
|
||||||
**WARNING:** Will be consolidated soon, prone to breaking changes.
|
|
||||||
Structure and default values:
|
|
||||||
```
|
|
||||||
threepid:
|
|
||||||
medium:
|
|
||||||
email:
|
|
||||||
identity:
|
|
||||||
from: ''
|
|
||||||
name: ''
|
|
||||||
connector: 'smtp'
|
|
||||||
generator: 'template'
|
|
||||||
connectors:
|
|
||||||
smtp:
|
|
||||||
host: ''
|
|
||||||
port: 587
|
|
||||||
tls: 1
|
|
||||||
login: ''
|
|
||||||
password: ''
|
|
||||||
generators:
|
|
||||||
template:
|
|
||||||
invite: 'classpath:threepids/email/invite-template.eml'
|
|
||||||
session:
|
|
||||||
validation:
|
|
||||||
local: 'classpath:threepids/email/validate-local-template.eml'
|
|
||||||
remote: 'classpath:threepids/email/validate-remote-template.eml'
|
|
||||||
msisdn:
|
|
||||||
connector: 'twilio'
|
|
||||||
generator: 'template'
|
|
||||||
connectors:
|
|
||||||
twilio:
|
|
||||||
accountSid: ''
|
|
||||||
authToken: ''
|
|
||||||
number: ''
|
|
||||||
generators:
|
|
||||||
template:
|
|
||||||
invite: 'classpath:threepids/sms/invite-template.txt'
|
|
||||||
session:
|
|
||||||
validation:
|
|
||||||
local: 'classpath:threepids/sms/validate-local-template.txt'
|
|
||||||
remote: 'classpath:threepids/sms/validate-remote-template.txt'
|
|
||||||
```
|
|
@@ -1,9 +0,0 @@
|
|||||||
# SendGrid Notification handler
|
|
||||||
To be completed. See [raw possible configuration items](https://github.com/kamax-io/mxisd/blob/master/src/main/resources/application.yaml#L172).
|
|
||||||
|
|
||||||
Enabled with:
|
|
||||||
```
|
|
||||||
notification:
|
|
||||||
handler:
|
|
||||||
email: 'sendgrid'
|
|
||||||
```
|
|
@@ -1,26 +1,30 @@
|
|||||||
# Web pages for the 3PID session processes
|
# Web pages for the 3PID sessions
|
||||||
You can customize the various pages used during a 3PID validation using [Thymeleaf templates](http://www.thymeleaf.org/).
|
You can customize the various pages used during a 3PID validation using [Thymeleaf templates](http://www.thymeleaf.org/).
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
Pseudo-configuration to illustrate the structure:
|
||||||
|
```yaml
|
||||||
|
# CONFIGURATION EXAMPLE
|
||||||
|
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
|
||||||
|
view.session.local:
|
||||||
|
onTokenSubmit:
|
||||||
|
success: '/path/to/session/local/tokenSubmitSuccess-page.html'
|
||||||
|
failure: '/path/to/session/local/tokenSubmitFailure-page.html'
|
||||||
|
view.session.localRemote:
|
||||||
|
onTokenSubmit:
|
||||||
|
success: '/path/to/session/localRemote/tokenSubmitSuccess-page.html'
|
||||||
|
failure: '/path/to/session/local/tokenSubmitFailure-page.html'
|
||||||
|
view.session.remote:
|
||||||
|
onRequest:
|
||||||
|
success: '/path/to/session/remote/requestSuccess-page.html'
|
||||||
|
failure: '/path/to/session/remote/requestFailure-page.html'
|
||||||
|
onCheck:
|
||||||
|
success: '/path/to/session/remote/checkSuccess-page.html'
|
||||||
|
failure: '/path/to/session/remote/checkFailure-page.html'
|
||||||
|
# CONFIGURATION EXAMPLE
|
||||||
|
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
|
||||||
```
|
```
|
||||||
view:
|
|
||||||
session:
|
|
||||||
local:
|
|
||||||
onTokenSubmit:
|
|
||||||
success: '/path/to/session/local/tokenSubmitSuccess-page.html'
|
|
||||||
failure: '/path/to/session/local/tokenSubmitFailure-page.html'
|
|
||||||
localRemote:
|
|
||||||
onTokenSubmit:
|
|
||||||
success: '/path/to/session/localRemote/tokenSubmitSuccess-page.html'
|
|
||||||
failure: '/path/to/session/local/tokenSubmitFailure-page.html'
|
|
||||||
remote:
|
|
||||||
onRequest:
|
|
||||||
success: '/path/to/session/remote/requestSuccess-page.html'
|
|
||||||
failure: '/path/to/session/remote/requestFailure-page.html'
|
|
||||||
onCheck:
|
|
||||||
success: '/path/to/session/remote/checkSuccess-page.html'
|
|
||||||
failure: '/path/to/session/remote/checkFailure-page.html'
|
|
||||||
```
|
|
||||||
3PID session are divided into three config sections:
|
3PID session are divided into three config sections:
|
||||||
- `local` for local-only 3PID sessions
|
- `local` for local-only 3PID sessions
|
||||||
- `localRemote` for local 3PID sessions that can also be turned into remote sessions, if the user so desires
|
- `localRemote` for local 3PID sessions that can also be turned into remote sessions, if the user so desires
|
@@ -6,7 +6,7 @@
|
|||||||
- [Session scope](#session-scope)
|
- [Session scope](#session-scope)
|
||||||
- [Notifications](#notifications)
|
- [Notifications](#notifications)
|
||||||
- [Email](#email)
|
- [Email](#email)
|
||||||
- [Phone numbers](#msisdn-phone-numbers)
|
- [Phone numbers](#msisdn-(phone-numbers))
|
||||||
- [Usage](#usage)
|
- [Usage](#usage)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Web views](#web-views)
|
- [Web views](#web-views)
|
||||||
@@ -17,49 +17,63 @@
|
|||||||
- [Sessions disabled](#sessions-disabled)
|
- [Sessions disabled](#sessions-disabled)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
When adding an email, a phone number or any other kind of 3PID (Third-Party Identifier) in a Matrix client,
|
When adding an email, a phone number or any other kind of 3PID (Third-Party Identifier) in a Matrix client,
|
||||||
the identity server is called to validate the 3PID.
|
the identity server is contacted to validate the 3PID.
|
||||||
|
|
||||||
|
To validate the 3PID the identity server sends a message to the 3PID (e.g. an
|
||||||
|
email) with a hyperlink back to a web-page managed by the identity server to
|
||||||
|
confirm ownership of the 3PID.
|
||||||
|
|
||||||
Once this 3PID is validated, the Homeserver will publish the user Matrix ID on the Identity Server and
|
Once this 3PID is validated, the Homeserver will publish the user Matrix ID on the Identity Server and
|
||||||
add this 3PID to the Matrix account which initiated the request.
|
add this 3PID to the Matrix account which initiated the request.
|
||||||
|
|
||||||
## Purpose
|
|
||||||
This serves two purposes:
|
This serves two purposes:
|
||||||
- Add the 3PID as an administrative/login info for the Homeserver directly
|
- Add the 3PID as an administrative/login info for the Homeserver directly
|
||||||
- Publish, or *Bind*, the 3PID so it can be queried from Homeservers and clients when inviting someone in a room
|
- Publish, or *Bind*, the 3PID so it can be queried from Homeservers and clients when inviting someone in a room
|
||||||
by a 3PID, allowing it to be resolved to a Matrix ID.
|
by a 3PID, allowing it to be resolved to a Matrix ID.
|
||||||
|
|
||||||
## Federation
|
## Federation
|
||||||
Federation is based on the principle that one can get a domain name and serve services and information within that
|
In a federated set up, identity servers must cooperate to find the Matrix ID associated with a 3PID.
|
||||||
domain namespace in a way which can be discovered following a specific protocol or specification.
|
|
||||||
|
|
||||||
In the Matrix eco-system, some 3PID can be federated (e.g. emails) while some others cannot (phone numbers).
|
Federation is based on the principle that each server is responsible for its own (dns) domain.
|
||||||
Also, Matrix users might add 3PIDs that would not point to the Identity server that actually holds the 3PID binding.
|
Therefore only those 3PID can be federated that can be distinguished by their
|
||||||
|
domain such as email addresses.
|
||||||
|
|
||||||
|
Example: a user from Homeserver `example.org` adds an email `john@example.com`.
|
||||||
|
Federated identity servers would try to find the identity server at `example.com` and ask it for the Matrix ID of associated with `john@example.com`.
|
||||||
|
|
||||||
|
Nevertheless, Matrix users might add 3PIDs that are not associated to a domain, for example telephone numbers.
|
||||||
|
Or they might even add 3PIDs associated to a different domain (such as an email address hosted by gmail).
|
||||||
|
Such 3PIDs cannot be resolved in a federated way.
|
||||||
|
|
||||||
Example: a user from Homeserver `example.org` adds an email `john@gmail.com`.
|
Example: a user from Homeserver `example.org` adds an email `john@gmail.com`.
|
||||||
If a federated lookup was performed, Identity servers would try to find the 3PID bind at the `gmail.com` server, and
|
If a federated lookup was performed, Identity servers would try to find the 3PID bind at the `gmail.com` server, and
|
||||||
not `example.org`.
|
not `example.org`.
|
||||||
|
|
||||||
To allow global publishing of 3PID bindings to be found anywhere within the current protocol specification, one would
|
In order to resolve such 3PIDs, i.e. 3PIDs that cannot be resolved in a Federated way, an identity server can be configured such that
|
||||||
perform a *Remote session* and *Remote bind*, effectively starting a new 3PID session with another Identity server on
|
- 3PIDs that cannot be resolved locally or using federation, are fowarded to another global identity server.
|
||||||
behalf of the user.
|
- registration of new 3PIDs that cannot be looked up in a federated fashion, is forwarded to another global identity server.
|
||||||
|
|
||||||
|
By forwarding a 3PIDs registration the identity creates a *Remote session* and *Remote bind*, effectively starting a new 3PID session with another Identity server on
|
||||||
|
behalf of the user.
|
||||||
|
|
||||||
To ensure lookup works consistency within the current Matrix network, the central Matrix.org Identity Server should be
|
To ensure lookup works consistency within the current Matrix network, the central Matrix.org Identity Server should be
|
||||||
used to store *remote* sessions and binds.
|
used to store *remote* sessions and binds.
|
||||||
|
|
||||||
On the flip side, at the time of writing, the Matrix specification and the central Matrix.org servers do not allow to
|
However, at the time of writing, the Matrix specification and the central Matrix.org servers do not allow to remote a 3PID bind.
|
||||||
remote a 3PID bind. This means that once a 3PID is published (email, phone number, etc.), it cannot be easily remove
|
This means that once a 3PID is published (email, phone number, etc.), it cannot be easily removed
|
||||||
and would require contacting the Matrix.org administrators for each bind individually.
|
and would require contacting the Matrix.org administrators for each bind individually.
|
||||||
This poses a privacy, control and security concern, especially for groups/corporations that want to keep a tight control
|
This poses a privacy, control and security concern, especially for groups/corporations that want to keep a tight control
|
||||||
on where such identifiers can be made publicly visible.
|
on where such identifiers can be made publicly visible.
|
||||||
|
|
||||||
To ensure full control, validation management rely on two concepts:
|
To ensure full control, validation management relies on two concepts:
|
||||||
- The scope of 3PID being validated
|
- The scope of 3PID being validated
|
||||||
- The scope of 3PID sessions that should be possible/offered
|
- The scope of 3PID sessions that should be possible/offered
|
||||||
|
|
||||||
### 3PID scope
|
### 3PID scope
|
||||||
3PID can either be scoped as local or remote.
|
3PID can either be scoped as local or remote.
|
||||||
|
|
||||||
Local means that they can looked up using federation and that such federation call would end up on the local
|
Local means that they can be looked up using federation and that such a federation call would end up on the local
|
||||||
Identity Server.
|
Identity Server.
|
||||||
Remote means that they cannot be lookup using federation or that a federation call would not end up on the local
|
Remote means that they cannot be lookup using federation or that a federation call would not end up on the local
|
||||||
Identity Server.
|
Identity Server.
|
||||||
@@ -80,9 +94,8 @@ Sessions can be scoped as:
|
|||||||
|
|
||||||
**IMPORTANT NOTE:** mxisd does not store bindings directly. While a user can see its email, phone number or any other
|
**IMPORTANT NOTE:** mxisd does not store bindings directly. While a user can see its email, phone number or any other
|
||||||
3PID in its settings/profile, it does **NOT** mean it is published anywhere and can be used to invite/search the user.
|
3PID in its settings/profile, it does **NOT** mean it is published anywhere and can be used to invite/search the user.
|
||||||
Identity backends (LDAP, REST, SQL) are the ones holding such data.
|
Identity stores are the ones holding such data.
|
||||||
If you still want added arbitrary 3PIDs to be discoverable on your local server, you will need to link mxisd to your
|
If you still want added arbitrary 3PIDs to be discoverable on a synapse Homeserver, use the corresponding [Identity store](../../stores/synapse.md).
|
||||||
synapse DB to make it an Identity backend.
|
|
||||||
|
|
||||||
See the [Scenarios](#scenarios) for more info on how and why.
|
See the [Scenarios](#scenarios) for more info on how and why.
|
||||||
|
|
||||||
@@ -99,120 +112,70 @@ Built-in generators and connectors for supported 3PID types:
|
|||||||
|
|
||||||
### Email
|
### Email
|
||||||
Generators:
|
Generators:
|
||||||
- [Template](../threepids/notifications/template-generator.md)
|
- [Template](../notification/template-generator.md)
|
||||||
|
|
||||||
Connectors:
|
Connectors:
|
||||||
- [SMTP](../threepids/medium/email/smtp-connector.md)
|
- [SMTP](../medium/email/smtp-connector.md)
|
||||||
|
|
||||||
#### MSISDN (Phone numbers)
|
#### MSISDN (Phone numbers)
|
||||||
Generators:
|
Generators:
|
||||||
- [Template](../threepids/notifications/template-generator.md)
|
- [Template](../notification/template-generator.md)
|
||||||
|
|
||||||
Connectors:
|
Connectors:
|
||||||
- [Twilio](../threepids/medium/msisdn/twilio-connector.md) with SMS
|
- [Twilio](../medium/msisdn/twilio-connector.md) with SMS
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
### Configuration
|
### Configuration
|
||||||
The following example of configuration (incomplete extract) shows which items are relevant for 3PID sessions.
|
The following example of configuration (incomplete extract) shows which items are relevant for 3PID sessions.
|
||||||
|
|
||||||
**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.
|
||||||
Please refer to the full example config file to see which keys are mandatory and to be included in your configuration.
|
```yaml
|
||||||
|
# CONFIGURATION EXAMPLE
|
||||||
|
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
|
||||||
|
session.policy.validation.enabled: true
|
||||||
|
session.policy.validation.forLocal:
|
||||||
|
enabled: true
|
||||||
|
toLocal: true
|
||||||
|
toRemote:
|
||||||
|
enabled: true
|
||||||
|
server: 'configExample' # Not to be included in config! Already present in default config!
|
||||||
|
session.policy.validation.forRemote:
|
||||||
|
enabled: true
|
||||||
|
toLocal: true
|
||||||
|
toRemote:
|
||||||
|
enabled: true
|
||||||
|
server: 'configExample' # Not to be included in config! Already present in default config!
|
||||||
|
# DO NOT COPY/PASTE THIS IN YOUR CONFIGURATION
|
||||||
|
# CONFIGURATION EXAMPLE
|
||||||
```
|
```
|
||||||
matrix:
|
|
||||||
identity:
|
|
||||||
servers:
|
|
||||||
configExample: # Not to be included in config! Already present in default config!
|
|
||||||
- 'https://example.org'
|
|
||||||
|
|
||||||
|
|
||||||
threepid:
|
|
||||||
medium:
|
|
||||||
email:
|
|
||||||
connector: 'example1' # Not to be included in config! Already present in default config!
|
|
||||||
generator: 'example2' # Not to be included in config! Already present in default config!
|
|
||||||
connectors:
|
|
||||||
example1:
|
|
||||||
generators:
|
|
||||||
example1:
|
|
||||||
key: "value"
|
|
||||||
example2:
|
|
||||||
key: "value"
|
|
||||||
|
|
||||||
session:
|
|
||||||
policy:
|
|
||||||
validation:
|
|
||||||
enabled: true
|
|
||||||
forLocal:
|
|
||||||
enabled: true
|
|
||||||
toLocal: true
|
|
||||||
toRemote:
|
|
||||||
enabled: true
|
|
||||||
server: 'configExample' # Not to be included in config! Already present in default config!
|
|
||||||
forRemote:
|
|
||||||
enabled: true
|
|
||||||
toLocal: false
|
|
||||||
toRemote:
|
|
||||||
enabled: true
|
|
||||||
server: 'configExample' # Not to be included in config! Already present in default config!
|
|
||||||
```
|
|
||||||
|
|
||||||
`matrix.identity.servers` is the namespace to configure arbitrary list of Identity servers with a label as parent key.
|
|
||||||
In the above example, the list with label `configExample` contains a single server entry pointing to `https://example.org`.
|
|
||||||
|
|
||||||
**NOTE:** The server list is set to `root` by default and should typically NOT be included in your config.
|
|
||||||
|
|
||||||
Identity server entry can be of two format:
|
|
||||||
- URL, bypassing any kind of domain and port discovery
|
|
||||||
- Domain name as `string`, allowing federated discovery to take place.
|
|
||||||
|
|
||||||
The label can be used in other places of the configuration, allowing you to only declare Identity servers once.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
`threepid.medium.<3PID>` is the namespace to configure 3PID specific items, not directly tied to any other component of
|
|
||||||
mxisd.
|
|
||||||
In the above example, only `email` is defined as 3PID type.
|
|
||||||
|
|
||||||
Each 3PID namespace comes with 4 configuration key allowing you to configure generators and connectors for notifications:
|
|
||||||
- `connectors` is a configuration namespace to be used for any connector configuration. Child keys represent the unique
|
|
||||||
ID for each connector.
|
|
||||||
- `generators` is a configuration namespace to be used for any generator configuration. Child keys represent the unique
|
|
||||||
ID for each generator.
|
|
||||||
- `connector` is given the ID of the connector to be used at runtime.
|
|
||||||
- `generator` is given the ID of the generator to be used at runtime.
|
|
||||||
|
|
||||||
In the above example, emails notifications are generated by the `example2` module and sent with the `example1` module.
|
|
||||||
By default, `template` is used as generator and `smtp` as connector.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
`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
|
||||||
are allowed to do in terms of 3PID sessions.
|
are allowed to do in terms of 3PID sessions.
|
||||||
|
|
||||||
The policy is divided contains a global on/off switch for 3PID sessions using `.enabled`
|
The policy has a global on/off switch for 3PID sessions using `.enabled`
|
||||||
It is also divided into two sections: `forLocal` and `forRemote` which refers to the 3PID scopes.
|
It is also divided into two sections: `forLocal` and `forRemote` which refers to the 3PID scopes.
|
||||||
|
|
||||||
Each scope is divided into three parts:
|
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.
|
||||||
|
|
||||||
### Web views
|
### Web views
|
||||||
Once a user click on a validation link, it is taken to the Identity Server validation page where the token is submited.
|
Once a user click on a validation link, it is taken to the Identity Server validation page where the token is submitted.
|
||||||
If the session or token is invalid, an error page is displayed.
|
If the session or token is invalid, an error page is displayed.
|
||||||
Workflow pages are also available for the remote 3PID session process.
|
Workflow pages are also available for the remote 3PID session process.
|
||||||
|
|
||||||
See [the dedicated document](3pid-views.md)
|
See [the dedicated document](session-views.md)
|
||||||
on how to configure/customize/brand those pages to your liking.
|
on how to configure/customize/brand those pages to your liking.
|
||||||
|
|
||||||
### Scenarios
|
### Scenarios
|
||||||
It is important to keep in mind that mxisd does not create bindings, irrelevant if a user added a 3PID to their profile.
|
It is important to keep in mind that mxisd does not create bindings, irrelevant if a user added a 3PID to their profile.
|
||||||
Instead, when queried for bindings, mxisd will query Identity backends which are responsible to store this kind of information.
|
Instead, when queried for bindings, mxisd will query Identity stores which are responsible to store this kind of information.
|
||||||
|
|
||||||
This has the side effect that any 3PID added to a user profile which is NOT within a configured and enabled Identity backend
|
This has the side effect that any 3PID added to a user profile which is NOT within a configured and enabled Identity backend
|
||||||
will simply not be usable for search or invites, **even on the same Homeserver!**
|
will simply not be usable for search or invites, **even on the same Homeserver!**
|
||||||
@@ -220,18 +183,17 @@ mxisd does not store binds on purpose, as one of its primary goal is to ensure m
|
|||||||
and the rest of the Matrix ecosystem is preserved.
|
and the rest of the Matrix ecosystem is preserved.
|
||||||
|
|
||||||
Nonetheless, because mxisd also aims at offering support for tight control over identity data, it is possible to have
|
Nonetheless, because mxisd also aims at offering support for tight control over identity data, it is possible to have
|
||||||
such 3PID bindings available for search and invite queries on the local Homeserver by using the `SQL` backend and
|
such 3PID bindings available for search and invite queries on synapse with the corresponding [Identity store](../../stores/synapse.md).
|
||||||
configuring it to use the synapse database. Support for `SQLite` and `PostgreSQL` is available.
|
|
||||||
|
|
||||||
See the [Local sessions only](#local-sessions-only) use case for more information on how to configure.
|
See the [Local sessions only](#local-sessions-only) use case for more information on how to configure.
|
||||||
|
|
||||||
#### Default
|
#### Default
|
||||||
By default, mxisd allows the following:
|
By default, mxisd allows the following:
|
||||||
|
|
||||||
| | Local Session | Remote Session |
|
| | Local Session | Remote Session |
|
||||||
|----------------|-------|--------|
|
|-----------------|-------------------|----------------|
|
||||||
| **Local 3PID** | Yes | Yes, offered |
|
| **Local 3PID** | Yes | Yes, offered |
|
||||||
| **Remote 3PID** | No, Remote forced | Yes |
|
| **Remote 3PID** | No, Remote forced | Yes |
|
||||||
|
|
||||||
This is usually what people expect and will feel natural to users and does not involve further integration.
|
This is usually what people expect and will feel natural to users and does not involve further integration.
|
||||||
|
|
||||||
@@ -243,8 +205,8 @@ Other e-mail addresses and phone number will be redirected to remote sessions to
|
|||||||
ecosystem and other federated servers.
|
ecosystem and other federated servers.
|
||||||
|
|
||||||
#### Local sessions only
|
#### Local sessions only
|
||||||
**NOTE:** This does not affect 3PID lookups (queries to find Matrix IDs) which will remain public due to limitation
|
**NOTE:** This does not affect 3PID lookups (queries to find Matrix IDs). See [Federation](../../features/federation.md)
|
||||||
in the Matrix protocol.
|
to disable remote lookup for those.
|
||||||
|
|
||||||
This configuration ensures maximum confidentiality and privacy.
|
This configuration ensures maximum confidentiality and privacy.
|
||||||
Typical use cases:
|
Typical use cases:
|
||||||
@@ -256,37 +218,22 @@ No 3PID will be sent to a remote Identity server and all validation will be perf
|
|||||||
On the flip side, people with *Remote* 3PID scopes will not be found from other servers.
|
On the flip side, people with *Remote* 3PID scopes will not be found from other servers.
|
||||||
|
|
||||||
Use the following values:
|
Use the following values:
|
||||||
```
|
```yaml
|
||||||
session:
|
session.policy.validation.enabled: true
|
||||||
policy:
|
session.policy.validation.forLocal:
|
||||||
validation:
|
enabled: true
|
||||||
enabled: true
|
toLocal: true
|
||||||
forLocal:
|
toRemote:
|
||||||
enabled: true
|
enabled: false
|
||||||
toLocal: true
|
session.policy.validation.forRemote:
|
||||||
toRemote:
|
enabled: true
|
||||||
enabled: false
|
toLocal: true
|
||||||
forRemote:
|
toRemote:
|
||||||
enabled: true
|
enabled: false
|
||||||
toLocal: true
|
|
||||||
toRemote:
|
|
||||||
enabled: false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**IMPORTANT**: When using local-only mode, you will also need to link mxisd to synapse if you want user searches and invites to work.
|
**IMPORTANT**: When using local-only mode and if you are using synapse, you will also need to enable its dedicated Identity
|
||||||
To do so, add/edit the following configuration keys:
|
store if you want user searches and invites to work. To do so, see the [dedicated document](../../stores/synapse.md).
|
||||||
```
|
|
||||||
synapseSql:
|
|
||||||
enabled: true
|
|
||||||
type: 'SET TO PROPER VALUE'
|
|
||||||
connection: 'SET TO PROPER VALUE'
|
|
||||||
```
|
|
||||||
- `synapseSql.enabled` set to `true` to activate the SQL backend.
|
|
||||||
- `synapseSql.type` can be set to `sqlite` or `postgresql`, depending on your synapse setup.
|
|
||||||
- `synapseSql.connection` use a JDBC format which is appened after the `jdbc:type:` connection URI.
|
|
||||||
Example values for each type:
|
|
||||||
- `sqlite`: `/path/to/homeserver.db`
|
|
||||||
- `postgresql`: `//localhost/database?user=synapse&password=synapse`
|
|
||||||
|
|
||||||
#### Remote sessions only
|
#### Remote sessions only
|
||||||
This configuration ensures all 3PID are made public for maximum compatibility and reach within the Matrix ecosystem, at
|
This configuration ensures all 3PID are made public for maximum compatibility and reach within the Matrix ecosystem, at
|
||||||
@@ -297,31 +244,25 @@ Typical use cases:
|
|||||||
- Homeserver with registration enabled
|
- Homeserver with registration enabled
|
||||||
|
|
||||||
Use the following values:
|
Use the following values:
|
||||||
```
|
```yaml
|
||||||
session:
|
session.policy.validation.enabled: true
|
||||||
policy:
|
session.policy.validation.forLocal:
|
||||||
validation:
|
enabled: true
|
||||||
enabled: true
|
toLocal: false
|
||||||
forLocal:
|
toRemote:
|
||||||
enabled: true
|
enabled: true
|
||||||
toLocal: false
|
session.policy.validation.forRemote:
|
||||||
toRemote:
|
enabled: true
|
||||||
enabled: true
|
toLocal: false
|
||||||
forRemote:
|
toRemote:
|
||||||
enabled: true
|
enabled: true
|
||||||
toLocal: false
|
|
||||||
toRemote:
|
|
||||||
enabled: true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Sessions disabled
|
#### Sessions disabled
|
||||||
This configuration would disable 3PID session altogether, preventing users from adding emails and/or phone numbers to
|
This configuration would disable 3PID session altogether, preventing users from adding emails and/or phone numbers to
|
||||||
their profiles.
|
their profiles.
|
||||||
This would be used if mxisd is also performing authentication for the Homeserver, typically with synapse and the
|
This would be used if mxisd is also performing authentication for the Homeserver, typically with synapse and the
|
||||||
[REST Auth module](https://github.com/kamax-io/matrix-synapse-rest-auth).
|
[REST password provider](https://github.com/kamax-io/matrix-synapse-rest-auth).
|
||||||
|
|
||||||
While this feature is not yet ready in the REST auth module, you would use this configuration mode to auto-populate 3PID
|
|
||||||
at user login and prevent any further add.
|
|
||||||
|
|
||||||
**This mode comes with several important restrictions:**
|
**This mode comes with several important restrictions:**
|
||||||
- This does not prevent users from removing 3PID from their profile. They would be unable to add them back!
|
- This does not prevent users from removing 3PID from their profile. They would be unable to add them back!
|
||||||
@@ -330,9 +271,6 @@ at user login and prevent any further add.
|
|||||||
It is therefore recommended to not fully disable sessions but instead restrict specific set of 3PID and Session scopes.
|
It is therefore recommended to not fully disable sessions but instead restrict specific set of 3PID and Session scopes.
|
||||||
|
|
||||||
Use the following values to enable this mode:
|
Use the following values to enable this mode:
|
||||||
```
|
```yaml
|
||||||
session:
|
session.policy.validation.enabled: false
|
||||||
policy:
|
|
||||||
validation:
|
|
||||||
enabled: false
|
|
||||||
```
|
```
|
@@ -1,6 +1,6 @@
|
|||||||
Package: mxisd
|
Package: mxisd
|
||||||
Maintainer: Kamax.io <foss@kamax.io>
|
Maintainer: Kamax.io <foss@kamax.io>
|
||||||
Homepage: https://github.com/kamax-io/mxisd
|
Homepage: https://github.com/kamax-matrix/mxisd
|
||||||
Description: Federated Matrix Identity Server
|
Description: Federated Matrix Identity Server
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: openjdk-8-jre | openjdk-8-jre-headless | openjdk-8-jdk | openjdk-8-jdk-headless
|
Depends: openjdk-8-jre | openjdk-8-jre-headless | openjdk-8-jdk | openjdk-8-jdk-headless
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -30,6 +30,10 @@ public class UserID {
|
|||||||
// stub for (de)serialization
|
// stub for (de)serialization
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserID(UserIdType type, String value) {
|
||||||
|
this(type.getId(), value);
|
||||||
|
}
|
||||||
|
|
||||||
public UserID(String type, String value) {
|
public UserID(String type, String value) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
139
src/main/java/io/kamax/mxisd/as/AppServiceHandler.java
Normal file
139
src/main/java/io/kamax/mxisd/as/AppServiceHandler.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.as;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import io.kamax.matrix.MatrixID;
|
||||||
|
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;
|
||||||
|
import io.kamax.mxisd.profile.ProfileManager;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AppServiceHandler {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(AppServiceHandler.class);
|
||||||
|
|
||||||
|
private MatrixConfig cfg;
|
||||||
|
private ProfileManager profiler;
|
||||||
|
private NotificationManager notif;
|
||||||
|
private Synapse synapse;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AppServiceHandler(MatrixConfig cfg, ProfileManager profiler, NotificationManager notif, Synapse synapse) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
this.profiler = profiler;
|
||||||
|
this.notif = notif;
|
||||||
|
this.synapse = synapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processTransaction(List<JsonObject> eventsJson) {
|
||||||
|
eventsJson.forEach(ev -> {
|
||||||
|
String evId = EventKey.Id.getStringOrNull(ev);
|
||||||
|
if (StringUtils.isBlank(evId)) {
|
||||||
|
log.warn("Event has no ID, skipping");
|
||||||
|
log.debug("Event:\n{}", GsonUtil.getPrettyForLog(ev));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.debug("Event {}: processing start", evId);
|
||||||
|
|
||||||
|
String roomId = EventKey.RoomId.getStringOrNull(ev);
|
||||||
|
if (StringUtils.isBlank(roomId)) {
|
||||||
|
log.debug("Event has no room ID, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String senderId = EventKey.Sender.getStringOrNull(ev);
|
||||||
|
if (StringUtils.isBlank(senderId)) {
|
||||||
|
log.debug("Event has no room ID, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_MatrixID sender = MatrixID.asAcceptable(senderId);
|
||||||
|
|
||||||
|
if (!StringUtils.equals("m.room.member", GsonUtil.getStringOrNull(ev, "type"))) {
|
||||||
|
log.debug("This is not a room membership event, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.equals("invite", GsonUtil.getStringOrNull(ev, "membership"))) {
|
||||||
|
log.debug("This is not an invite event, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String inviteeId = EventKey.StateKey.getStringOrNull(ev);
|
||||||
|
if (StringUtils.isBlank(inviteeId)) {
|
||||||
|
log.warn("Invalid event: No invitee ID, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_MatrixID invitee = MatrixID.asAcceptable(inviteeId);
|
||||||
|
if (!StringUtils.equals(invitee.getDomain(), cfg.getDomain())) {
|
||||||
|
log.debug("Ignoring invite for {}: not a local user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Got invite for {}", inviteeId);
|
||||||
|
|
||||||
|
boolean wasSent = false;
|
||||||
|
List<_ThreePid> tpids = profiler.getThreepids(invitee).stream()
|
||||||
|
.filter(tpid -> ThreePidMedium.Email.is(tpid.getMedium()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
log.info("Found {} email(s) in identity store for {}", tpids.size(), inviteeId);
|
||||||
|
|
||||||
|
for (_ThreePid tpid : tpids) {
|
||||||
|
log.info("Found Email to notify about room invitation: {}", tpid.getAddress());
|
||||||
|
Map<String, String> properties = new HashMap<>();
|
||||||
|
profiler.getDisplayName(sender).ifPresent(name -> properties.put("sender_display_name", name));
|
||||||
|
try {
|
||||||
|
synapse.getRoomName(roomId).ifPresent(name -> properties.put("room_name", name));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.warn("Could not fetch room name", e);
|
||||||
|
log.warn("Unable to fetch room name: Did you integrate your Homeserver as documented?");
|
||||||
|
}
|
||||||
|
|
||||||
|
IMatrixIdInvite inv = new MatrixIdInvite(roomId, sender, invitee, tpid.getMedium(), tpid.getAddress(), properties);
|
||||||
|
notif.sendForInvite(inv);
|
||||||
|
log.info("Notification for invite of {} sent to {}", inviteeId, tpid.getAddress());
|
||||||
|
wasSent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Was notification sent? {}", wasSent);
|
||||||
|
|
||||||
|
log.debug("Event {}: processing end", evId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/main/java/io/kamax/mxisd/as/IMatrixIdInvite.java
Normal file
30
src/main/java/io/kamax/mxisd/as/IMatrixIdInvite.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.as;
|
||||||
|
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.mxisd.invitation.IThreePidInvite;
|
||||||
|
|
||||||
|
public interface IMatrixIdInvite extends IThreePidInvite {
|
||||||
|
|
||||||
|
_MatrixID getInvitee();
|
||||||
|
|
||||||
|
}
|
77
src/main/java/io/kamax/mxisd/as/MatrixIdInvite.java
Normal file
77
src/main/java/io/kamax/mxisd/as/MatrixIdInvite.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.as;
|
||||||
|
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MatrixIdInvite implements IMatrixIdInvite {
|
||||||
|
|
||||||
|
private String roomId;
|
||||||
|
private _MatrixID sender;
|
||||||
|
private _MatrixID invitee;
|
||||||
|
private String medium;
|
||||||
|
private String address;
|
||||||
|
private Map<String, String> properties;
|
||||||
|
|
||||||
|
public MatrixIdInvite(String roomId, _MatrixID sender, _MatrixID invitee, String medium, String address, Map<String, String> properties) {
|
||||||
|
this.roomId = Objects.requireNonNull(roomId);
|
||||||
|
this.sender = Objects.requireNonNull(sender);
|
||||||
|
this.invitee = Objects.requireNonNull(invitee);
|
||||||
|
this.medium = Objects.requireNonNull(medium);
|
||||||
|
this.address = Objects.requireNonNull(address);
|
||||||
|
this.properties = new HashMap<>(Objects.requireNonNull(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public _MatrixID getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMedium() {
|
||||||
|
return medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public _MatrixID getInvitee() {
|
||||||
|
return invitee;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRoomId() {
|
||||||
|
return roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -59,9 +59,10 @@ public class AuthManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("Attempting authentication with store {}", provider.getClass().getSimpleName());
|
||||||
|
|
||||||
BackendAuthResult result = provider.authenticate(mxid, password);
|
BackendAuthResult result = provider.authenticate(mxid, password);
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
|
|
||||||
String mxId;
|
String mxId;
|
||||||
if (UserIdType.Localpart.is(result.getId().getType())) {
|
if (UserIdType.Localpart.is(result.getId().getType())) {
|
||||||
mxId = MatrixID.from(result.getId().getValue(), mxCfg.getDomain()).acceptable().getId();
|
mxId = MatrixID.from(result.getId().getValue(), mxCfg.getDomain()).acceptable().getId();
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -38,6 +38,10 @@ public class BackendAuthResult {
|
|||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
public Set<ThreePid> getThreePids() {
|
public Set<ThreePid> getThreePids() {
|
||||||
return threePids;
|
return threePids;
|
||||||
}
|
}
|
||||||
@@ -73,6 +77,10 @@ public class BackendAuthResult {
|
|||||||
private UserID id;
|
private UserID id;
|
||||||
private BackendAuthProfile profile = new BackendAuthProfile();
|
private BackendAuthProfile profile = new BackendAuthProfile();
|
||||||
|
|
||||||
|
public void setSuccess(boolean success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean isSuccess() {
|
public Boolean isSuccess() {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -81,6 +89,10 @@ public class BackendAuthResult {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setId(UserID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public BackendAuthProfile getProfile() {
|
public BackendAuthProfile getProfile() {
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.auth.provider.BackendAuthResult;
|
||||||
|
|
||||||
|
public class ExecAuthResult extends BackendAuthResult {
|
||||||
|
|
||||||
|
private int exitStatus;
|
||||||
|
|
||||||
|
public int getExitStatus() {
|
||||||
|
return exitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExitStatus(int exitStatus) {
|
||||||
|
this.exitStatus = exitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
129
src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java
Normal file
129
src/main/java/io/kamax/mxisd/backend/exec/ExecAuthStore.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
|
import io.kamax.mxisd.UserID;
|
||||||
|
import io.kamax.mxisd.UserIdType;
|
||||||
|
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
||||||
|
import io.kamax.mxisd.backend.rest.RestAuthRequestJson;
|
||||||
|
import io.kamax.mxisd.config.ExecConfig;
|
||||||
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(ExecAuthStore.class);
|
||||||
|
|
||||||
|
private ExecConfig.Auth cfg;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ExecAuthStore(ExecConfig cfg) {
|
||||||
|
this.cfg = Objects.requireNonNull(cfg.getAuth());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return cfg.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecAuthResult authenticate(_MatrixID uId, String password) {
|
||||||
|
Objects.requireNonNull(uId);
|
||||||
|
Objects.requireNonNull(password);
|
||||||
|
|
||||||
|
log.info("Performing authentication for {}", uId.getId());
|
||||||
|
|
||||||
|
ExecAuthResult result = new ExecAuthResult();
|
||||||
|
result.setId(new UserID(UserIdType.Localpart, uId.getLocalPart()));
|
||||||
|
|
||||||
|
Processor<ExecAuthResult> p = new Processor<>(cfg);
|
||||||
|
|
||||||
|
p.addTokenMapper(cfg.getToken().getLocalpart(), uId::getLocalPart);
|
||||||
|
p.addTokenMapper(cfg.getToken().getDomain(), uId::getDomain);
|
||||||
|
p.addTokenMapper(cfg.getToken().getMxid(), uId::getId);
|
||||||
|
p.addTokenMapper(cfg.getToken().getPassword(), () -> password);
|
||||||
|
|
||||||
|
p.addJsonInputTemplate(tokens -> {
|
||||||
|
RestAuthRequestJson json = new RestAuthRequestJson();
|
||||||
|
json.setLocalpart(tokens.getLocalpart());
|
||||||
|
json.setDomain(tokens.getDomain());
|
||||||
|
json.setMxid(tokens.getMxid());
|
||||||
|
json.setPassword(tokens.getPassword());
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
p.addInputTemplate(PlainType, tokens -> tokens.getLocalpart() + System.lineSeparator() +
|
||||||
|
tokens.getDomain() + System.lineSeparator() +
|
||||||
|
tokens.getMxid() + System.lineSeparator() +
|
||||||
|
tokens.getPassword() + System.lineSeparator()
|
||||||
|
);
|
||||||
|
|
||||||
|
p.withExitHandler(pr -> result.setExitStatus(pr.getExitValue()));
|
||||||
|
|
||||||
|
p.withSuccessHandler(pr -> result.setSuccess(true));
|
||||||
|
p.withSuccessDefault(o -> result);
|
||||||
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
|
JsonObject data = GsonUtil.getObj(GsonUtil.parseObj(output), "auth");
|
||||||
|
GsonUtil.findPrimitive(data, "success")
|
||||||
|
.map(JsonPrimitive::getAsBoolean)
|
||||||
|
.ifPresent(result::setSuccess);
|
||||||
|
GsonUtil.findObj(data, "profile")
|
||||||
|
.flatMap(profile -> GsonUtil.findString(profile, "display_name"))
|
||||||
|
.ifPresent(v -> result.getProfile().setDisplayName(v));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
p.addSuccessMapper(PlainType, output -> {
|
||||||
|
String[] lines = output.split("\\R");
|
||||||
|
if (lines.length > 2) {
|
||||||
|
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setSuccess(Optional.ofNullable(StringUtils.isEmpty(lines[0]) ? null : lines[0])
|
||||||
|
.map(v -> StringUtils.equalsAnyIgnoreCase(v, "true", "1"))
|
||||||
|
.orElse(result.isSuccess()));
|
||||||
|
|
||||||
|
if (lines.length == 2) {
|
||||||
|
Optional.ofNullable(StringUtils.isEmpty(lines[1]) ? null : lines[1])
|
||||||
|
.ifPresent(v -> result.getProfile().setDisplayName(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
p.withFailureHandler(pr -> result.setSuccess(false));
|
||||||
|
p.withFailureDefault(o -> result);
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import io.kamax.matrix.MatrixID;
|
||||||
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
|
import io.kamax.mxisd.config.ExecConfig;
|
||||||
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
|
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest;
|
||||||
|
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult;
|
||||||
|
import io.kamax.mxisd.directory.IDirectoryProvider;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider {
|
||||||
|
|
||||||
|
private ExecConfig.Directory cfg;
|
||||||
|
private MatrixConfig mxCfg;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ExecDirectoryStore(ExecConfig cfg, MatrixConfig mxCfg) {
|
||||||
|
this(cfg.getDirectory(), mxCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecDirectoryStore(ExecConfig.Directory cfg, MatrixConfig mxCfg) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
this.mxCfg = mxCfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return cfg.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserDirectorySearchResult search(ExecConfig.Process cfg, UserDirectorySearchRequest request) {
|
||||||
|
if (StringUtils.isEmpty(cfg.getCommand())) {
|
||||||
|
return UserDirectorySearchResult.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Processor<UserDirectorySearchResult> p = new Processor<>(cfg);
|
||||||
|
|
||||||
|
p.addJsonInputTemplate(tokens -> new UserDirectorySearchRequest(tokens.getType(), tokens.getQuery()));
|
||||||
|
p.addInputTemplate(PlainType, tokens -> tokens.getType() + System.lineSeparator() + tokens.getQuery());
|
||||||
|
|
||||||
|
p.addTokenMapper(cfg.getToken().getType(), request::getBy);
|
||||||
|
p.addTokenMapper(cfg.getToken().getQuery(), request::getSearchTerm);
|
||||||
|
|
||||||
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
|
if (StringUtils.isBlank(output)) {
|
||||||
|
return UserDirectorySearchResult.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDirectorySearchResult response = GsonUtil.get().fromJson(output, UserDirectorySearchResult.class);
|
||||||
|
for (UserDirectorySearchResult.Result result : response.getResults()) {
|
||||||
|
result.setUserId(MatrixID.asAcceptable(result.getUserId(), mxCfg.getDomain()).getId());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
p.withFailureDefault(output -> new UserDirectorySearchResult());
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDirectorySearchResult searchByDisplayName(String query) {
|
||||||
|
return search(cfg.getSearch().getByName(), new UserDirectorySearchRequest("name", query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDirectorySearchResult searchBy3pid(String query) {
|
||||||
|
return search(cfg.getSearch().getByName(), new UserDirectorySearchRequest("threepid", query));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
209
src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java
Normal file
209
src/main/java/io/kamax/mxisd/backend/exec/ExecIdentityStore.java
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import io.kamax.matrix.MatrixID;
|
||||||
|
import io.kamax.matrix.ThreePid;
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
|
import io.kamax.mxisd.UserID;
|
||||||
|
import io.kamax.mxisd.UserIdType;
|
||||||
|
import io.kamax.mxisd.backend.rest.LookupBulkResponseJson;
|
||||||
|
import io.kamax.mxisd.backend.rest.LookupSingleResponseJson;
|
||||||
|
import io.kamax.mxisd.config.ExecConfig;
|
||||||
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
|
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||||
|
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||||
|
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||||
|
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(ExecIdentityStore.class);
|
||||||
|
|
||||||
|
private final ExecConfig.Identity cfg;
|
||||||
|
private final MatrixConfig mxCfg;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ExecIdentityStore(ExecConfig cfg, MatrixConfig mxCfg) {
|
||||||
|
this(cfg.getIdentity(), mxCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecIdentityStore(ExecConfig.Identity cfg, MatrixConfig mxCfg) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
this.mxCfg = mxCfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return cfg.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLocal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return cfg.getPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExecConfig.Process getSingleCfg() {
|
||||||
|
return cfg.getLookup().getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _MatrixID getUserId(UserID id) {
|
||||||
|
if (Objects.isNull(id)) {
|
||||||
|
throw new JsonParseException("User id key is not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserIdType.Localpart.is(id.getType())) {
|
||||||
|
return MatrixID.asAcceptable(id.getValue(), mxCfg.getDomain());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserIdType.MatrixID.is(id.getType())) {
|
||||||
|
return MatrixID.asAcceptable(id.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InternalServerError("Unknown user type: " + id.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<SingleLookupReply> find(SingleLookupRequest request) {
|
||||||
|
Processor<Optional<SingleLookupReply>> p = new Processor<>();
|
||||||
|
p.withConfig(cfg.getLookup().getSingle());
|
||||||
|
|
||||||
|
p.addTokenMapper(getSingleCfg().getToken().getMedium(), request::getType);
|
||||||
|
p.addTokenMapper(getSingleCfg().getToken().getAddress(), request::getThreePid);
|
||||||
|
|
||||||
|
p.addJsonInputTemplate(tokens -> new ThreePid(tokens.getMedium(), tokens.getAddress()));
|
||||||
|
p.addInputTemplate(PlainType, tokens -> tokens.getMedium()
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ tokens.getAddress()
|
||||||
|
);
|
||||||
|
|
||||||
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
|
if (StringUtils.isBlank(output)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GsonUtil.findObj(GsonUtil.parseObj(output), "lookup")
|
||||||
|
.filter(obj -> !obj.entrySet().isEmpty())
|
||||||
|
.map(json -> GsonUtil.get().fromJson(json, LookupSingleResponseJson.class))
|
||||||
|
.map(lookup -> getUserId(lookup.getId()))
|
||||||
|
.map(mxId -> new SingleLookupReply(request, mxId));
|
||||||
|
});
|
||||||
|
|
||||||
|
p.addSuccessMapper(PlainType, output -> {
|
||||||
|
String[] lines = output.split("\\R");
|
||||||
|
if (lines.length > 2) {
|
||||||
|
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines.length == 1 && StringUtils.isBlank(lines[0])) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = StringUtils.trimToEmpty(lines.length == 1 ? UserIdType.Localpart.getId() : lines[0]);
|
||||||
|
String value = StringUtils.trimToEmpty(lines.length == 2 ? lines[1] : lines[0]);
|
||||||
|
|
||||||
|
if (UserIdType.Localpart.is(type)) {
|
||||||
|
return Optional.of(new SingleLookupReply(request, MatrixID.asAcceptable(value, mxCfg.getDomain())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserIdType.MatrixID.is(type)) {
|
||||||
|
return Optional.of(new SingleLookupReply(request, MatrixID.asAcceptable(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InternalServerError("Invalid user type: " + type);
|
||||||
|
});
|
||||||
|
|
||||||
|
p.withFailureDefault(o -> Optional.empty());
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreePidMapping> populate(List<ThreePidMapping> mappings) {
|
||||||
|
Processor<List<ThreePidMapping>> p = new Processor<>();
|
||||||
|
p.withConfig(cfg.getLookup().getBulk());
|
||||||
|
|
||||||
|
p.addInput(JsonType, () -> {
|
||||||
|
JsonArray tpids = GsonUtil.asArray(mappings.stream()
|
||||||
|
.map(mapping -> GsonUtil.get().toJsonTree(new ThreePid(mapping.getMedium(), mapping.getValue())))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
return GsonUtil.get().toJson(GsonUtil.makeObj("lookup", tpids));
|
||||||
|
});
|
||||||
|
p.addInput(PlainType, () -> {
|
||||||
|
StringBuilder input = new StringBuilder();
|
||||||
|
for (ThreePidMapping mapping : mappings) {
|
||||||
|
input.append(mapping.getMedium()).append("\t").append(mapping.getValue()).append(System.lineSeparator());
|
||||||
|
}
|
||||||
|
return input.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
|
if (StringUtils.isBlank(output)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
LookupBulkResponseJson response = GsonUtil.get().fromJson(output, LookupBulkResponseJson.class);
|
||||||
|
return response.getLookup().stream().map(item -> {
|
||||||
|
ThreePidMapping mapping = new ThreePidMapping();
|
||||||
|
mapping.setMedium(item.getMedium());
|
||||||
|
mapping.setValue(item.getAddress());
|
||||||
|
|
||||||
|
if (UserIdType.Localpart.is(item.getId().getType())) {
|
||||||
|
mapping.setValue(MatrixID.asAcceptable(item.getId().getValue(), mxCfg.getDomain()).getId());
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserIdType.MatrixID.is(item.getId().getType())) {
|
||||||
|
mapping.setValue(MatrixID.asAcceptable(item.getId().getValue()).getId());
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InternalServerError("Invalid user type: " + item.getId().getType());
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
});
|
||||||
|
|
||||||
|
p.withFailureDefault(output -> Collections.emptyList());
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
103
src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java
Normal file
103
src/main/java/io/kamax/mxisd/backend/exec/ExecProfileStore.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.matrix._ThreePid;
|
||||||
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
|
import io.kamax.mxisd.config.ExecConfig;
|
||||||
|
import io.kamax.mxisd.profile.JsonProfileRequest;
|
||||||
|
import io.kamax.mxisd.profile.JsonProfileResult;
|
||||||
|
import io.kamax.mxisd.profile.ProfileProvider;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ExecProfileStore extends ExecStore implements ProfileProvider {
|
||||||
|
|
||||||
|
private ExecConfig.Profile cfg;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ExecProfileStore(ExecConfig cfg) {
|
||||||
|
this(cfg.getProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecProfileStore(ExecConfig.Profile cfg) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return cfg.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<JsonProfileResult> getFull(_MatrixID userId, ExecConfig.Process cfg) {
|
||||||
|
Processor<Optional<JsonProfileResult>> p = new Processor<>(cfg);
|
||||||
|
|
||||||
|
p.addJsonInputTemplate(tokens -> new JsonProfileRequest(tokens.getLocalpart(), tokens.getDomain(), tokens.getMxid()));
|
||||||
|
p.addInputTemplate(PlainType, tokens -> tokens.getLocalpart() + System.lineSeparator()
|
||||||
|
+ tokens.getDomain() + System.lineSeparator()
|
||||||
|
+ tokens.getMxid() + System.lineSeparator()
|
||||||
|
);
|
||||||
|
|
||||||
|
p.addTokenMapper(cfg.getToken().getLocalpart(), userId::getLocalPart);
|
||||||
|
p.addTokenMapper(cfg.getToken().getDomain(), userId::getDomain);
|
||||||
|
p.addTokenMapper(cfg.getToken().getMxid(), userId::getId);
|
||||||
|
|
||||||
|
p.withFailureDefault(v -> Optional.empty());
|
||||||
|
|
||||||
|
p.addSuccessMapper(JsonType, output -> {
|
||||||
|
if (StringUtils.isBlank(output)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GsonUtil.findObj(GsonUtil.parseObj(output), "profile")
|
||||||
|
.map(obj -> GsonUtil.get().fromJson(obj, JsonProfileResult.class));
|
||||||
|
});
|
||||||
|
|
||||||
|
return p.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getDisplayName(_MatrixID userId) {
|
||||||
|
return getFull(userId, cfg.getDisplayName()).map(JsonProfileResult::getDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<_ThreePid> getThreepids(_MatrixID userId) {
|
||||||
|
return getFull(userId, cfg.getThreePid())
|
||||||
|
.map(p -> Collections.<_ThreePid>unmodifiableList(p.getThreepids()))
|
||||||
|
.orElseGet(Collections::emptyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRoles(_MatrixID userId) {
|
||||||
|
return getFull(userId, cfg.getRole())
|
||||||
|
.map(JsonProfileResult::getRoles)
|
||||||
|
.orElseGet(Collections::emptyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
252
src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java
Normal file
252
src/main/java/io/kamax/mxisd/backend/exec/ExecStore.java
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.exec;
|
||||||
|
|
||||||
|
import io.kamax.matrix.json.GsonUtil;
|
||||||
|
import io.kamax.mxisd.config.ExecConfig;
|
||||||
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.zeroturnaround.exec.ProcessExecutor;
|
||||||
|
import org.zeroturnaround.exec.ProcessResult;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ExecStore {
|
||||||
|
|
||||||
|
public static final String JsonType = "json";
|
||||||
|
public static final String PlainType = "plain";
|
||||||
|
|
||||||
|
protected static String toJson(Object o) {
|
||||||
|
return GsonUtil.get().toJson(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(ExecStore.class);
|
||||||
|
|
||||||
|
private Supplier<ProcessExecutor> executorSupplier = () -> new ProcessExecutor().readOutput(true);
|
||||||
|
|
||||||
|
public void setExecutorSupplier(Supplier<ProcessExecutor> supplier) {
|
||||||
|
executorSupplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Processor<V> {
|
||||||
|
|
||||||
|
private ExecConfig.Process cfg;
|
||||||
|
|
||||||
|
private Supplier<Optional<String>> inputSupplier;
|
||||||
|
private Function<String, String> inputTypeMapper;
|
||||||
|
private Function<String, String> inputUnknownTypeMapper;
|
||||||
|
private Map<String, Supplier<String>> inputTypeSuppliers;
|
||||||
|
|
||||||
|
private Map<String, Function<ExecConfig.TokenOverride, String>> inputTypeTemplates;
|
||||||
|
private Supplier<String> inputTypeNoTemplateHandler;
|
||||||
|
private Map<String, Supplier<String>> tokenMappers;
|
||||||
|
private Function<String, String> tokenHandler;
|
||||||
|
|
||||||
|
private Consumer<ProcessResult> onExitHandler;
|
||||||
|
private Consumer<ProcessResult> successHandler;
|
||||||
|
private Map<String, Function<String, V>> successMappers;
|
||||||
|
private Function<String, V> successDefault;
|
||||||
|
private Consumer<ProcessResult> failureHandler;
|
||||||
|
private Map<String, Function<String, V>> failureMappers;
|
||||||
|
private Function<String, V> failureDefault;
|
||||||
|
private Consumer<ProcessResult> unknownHandler;
|
||||||
|
private Map<String, Function<String, V>> unknownMappers;
|
||||||
|
private Function<String, V> unknownDefault;
|
||||||
|
|
||||||
|
public Processor(ExecConfig.Process cfg) {
|
||||||
|
this();
|
||||||
|
withConfig(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Processor() {
|
||||||
|
tokenMappers = new HashMap<>();
|
||||||
|
inputTypeSuppliers = new HashMap<>();
|
||||||
|
inputTypeTemplates = new HashMap<>();
|
||||||
|
|
||||||
|
withTokenHandler(tokenHandler = input -> {
|
||||||
|
for (Map.Entry<String, Supplier<String>> entry : tokenMappers.entrySet()) {
|
||||||
|
input = input.replace(entry.getKey(), entry.getValue().get());
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
});
|
||||||
|
|
||||||
|
inputTypeNoTemplateHandler = () -> cfg.getInput().getType()
|
||||||
|
.map(type -> inputTypeTemplates.get(type).apply(cfg.getToken()))
|
||||||
|
.orElse("");
|
||||||
|
|
||||||
|
inputUnknownTypeMapper = type -> tokenHandler.apply(cfg.getInput().getTemplate().orElseGet(inputTypeNoTemplateHandler));
|
||||||
|
|
||||||
|
inputTypeMapper = type -> {
|
||||||
|
if (!inputTypeSuppliers.containsKey(type)) {
|
||||||
|
return inputUnknownTypeMapper.apply(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputTypeSuppliers.get(type).get();
|
||||||
|
};
|
||||||
|
|
||||||
|
inputSupplier = () -> cfg.getInput().getType().map(type -> inputTypeMapper.apply(type));
|
||||||
|
|
||||||
|
withExitHandler(pr -> {
|
||||||
|
});
|
||||||
|
|
||||||
|
successHandler = pr -> {
|
||||||
|
};
|
||||||
|
successMappers = new HashMap<>();
|
||||||
|
successDefault = output -> {
|
||||||
|
log.info("{} stdout: {}{}", cfg.getCommand(), System.lineSeparator(), output);
|
||||||
|
throw new InternalServerError("Exec command has no success handler configured. This is a bug. Please report.");
|
||||||
|
};
|
||||||
|
|
||||||
|
failureHandler = pr -> {
|
||||||
|
};
|
||||||
|
failureMappers = new HashMap<>();
|
||||||
|
failureDefault = output -> {
|
||||||
|
log.info("{} stdout: {}{}", cfg.getCommand(), System.lineSeparator(), output);
|
||||||
|
throw new InternalServerError("Exec command has no failure handler configured. This is a bug. Please report.");
|
||||||
|
};
|
||||||
|
|
||||||
|
unknownHandler = pr -> log.warn("Unexpected exit status: {}", pr.getExitValue());
|
||||||
|
unknownMappers = new HashMap<>();
|
||||||
|
withUnknownDefault(output -> {
|
||||||
|
log.error("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
|
||||||
|
throw new InternalServerError("Exec command returned with unexpected exit status");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withConfig(ExecConfig.Process cfg) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTokenMapper(String token, Supplier<String> data) {
|
||||||
|
tokenMappers.put(token, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withTokenHandler(Function<String, String> handler) {
|
||||||
|
tokenHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInput(String type, Supplier<String> handler) {
|
||||||
|
inputTypeSuppliers.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addInputTemplate(String type, Function<ExecConfig.TokenOverride, String> template) {
|
||||||
|
inputTypeTemplates.put(type, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addJsonInputTemplate(Function<ExecConfig.TokenOverride, Object> template) {
|
||||||
|
inputTypeTemplates.put(JsonType, token -> GsonUtil.get().toJson(template.apply(token)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withExitHandler(Consumer<ProcessResult> handler) {
|
||||||
|
onExitHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withSuccessHandler(Consumer<ProcessResult> handler) {
|
||||||
|
successHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSuccessMapper(String type, Function<String, V> mapper) {
|
||||||
|
successMappers.put(type, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withSuccessDefault(Function<String, V> mapper) {
|
||||||
|
successDefault = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withFailureHandler(Consumer<ProcessResult> handler) {
|
||||||
|
failureHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFailureMapper(String type, Function<String, V> mapper) {
|
||||||
|
failureMappers.put(type, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withFailureDefault(Function<String, V> mapper) {
|
||||||
|
failureDefault = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUnknownMapper(String type, Function<String, V> mapper) {
|
||||||
|
unknownMappers.put(type, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withUnknownDefault(Function<String, V> mapper) {
|
||||||
|
unknownDefault = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public V execute() {
|
||||||
|
log.info("Executing {}", cfg.getCommand());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProcessExecutor psExec = executorSupplier.get();
|
||||||
|
|
||||||
|
List<String> args = new ArrayList<>();
|
||||||
|
args.add(tokenHandler.apply(cfg.getCommand()));
|
||||||
|
args.addAll(cfg.getArgs().stream().map(arg -> tokenHandler.apply(arg)).collect(Collectors.toList()));
|
||||||
|
psExec.command(args);
|
||||||
|
|
||||||
|
psExec.environment(new HashMap<>(cfg.getEnv()).entrySet().stream()
|
||||||
|
.peek(e -> e.setValue(tokenHandler.apply(e.getValue())))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||||
|
|
||||||
|
inputSupplier.get().ifPresent(input -> psExec.redirectInput(IOUtils.toInputStream(input, StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
|
ProcessResult psResult = psExec.execute();
|
||||||
|
String output = psResult.outputUTF8();
|
||||||
|
onExitHandler.accept(psResult);
|
||||||
|
|
||||||
|
if (cfg.getExit().getSuccess().contains(psResult.getExitValue())) {
|
||||||
|
successHandler.accept(psResult);
|
||||||
|
|
||||||
|
return cfg.getOutput().getType()
|
||||||
|
.map(type -> successMappers.getOrDefault(type, successDefault).apply(output))
|
||||||
|
.orElseGet(() -> successDefault.apply(output));
|
||||||
|
} else if (cfg.getExit().getFailure().contains(psResult.getExitValue())) {
|
||||||
|
failureHandler.accept(psResult);
|
||||||
|
|
||||||
|
return cfg.getOutput().getType()
|
||||||
|
.map(type -> failureMappers.getOrDefault(type, failureDefault).apply(output))
|
||||||
|
.orElseGet(() -> failureDefault.apply(output));
|
||||||
|
} else {
|
||||||
|
unknownHandler.accept(psResult);
|
||||||
|
|
||||||
|
return cfg.getOutput().getType()
|
||||||
|
.map(type -> unknownMappers.getOrDefault(type, unknownDefault).apply(output))
|
||||||
|
.orElseGet(() -> unknownDefault.apply(output));
|
||||||
|
}
|
||||||
|
} catch (RuntimeException | IOException | InterruptedException | TimeoutException e) {
|
||||||
|
log.error("Failed to execute {}", cfg.getCommand());
|
||||||
|
log.debug("Internal exception:", e);
|
||||||
|
throw new InternalServerError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -49,7 +49,7 @@ public class GoogleFirebaseProvider extends GoogleFirebaseBackend implements ITh
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getMxid(UserRecord record) {
|
private String getMxid(UserRecord record) {
|
||||||
return new MatrixID(record.getUid(), domain).getId();
|
return MatrixID.asAcceptable(record.getUid(), domain).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd.backend.ldap;
|
package io.kamax.mxisd.backend.ldap;
|
||||||
|
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
import io.kamax.mxisd.config.MatrixConfig;
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
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;
|
||||||
@@ -70,7 +71,7 @@ public abstract class LdapBackend {
|
|||||||
return getAt().getUid().getValue();
|
return getAt().getUid().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected synchronized LdapConnection getConn() throws LdapException {
|
protected synchronized LdapConnection getConn() {
|
||||||
return new LdapNetworkConnection(cfg.getConnection().getHost(), cfg.getConnection().getPort(), cfg.getConnection().isTls());
|
return new LdapNetworkConnection(cfg.getConnection().getHost(), cfg.getConnection().getPort(), cfg.getConnection().isTls());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +125,17 @@ public abstract class LdapBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String buildUidFromMatrixId(_MatrixID mxId) {
|
||||||
|
String uidType = getCfg().getAttribute().getUid().getType();
|
||||||
|
if (StringUtils.equals(UID, uidType)) {
|
||||||
|
return mxId.getLocalPart();
|
||||||
|
} else if (StringUtils.equals(MATRIX_ID, uidType)) {
|
||||||
|
return mxId.getId();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Bind type " + uidType + " is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.ldap;
|
||||||
|
|
||||||
|
import io.kamax.matrix.ThreePid;
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.matrix._ThreePid;
|
||||||
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
|
import io.kamax.mxisd.config.ldap.LdapConfig;
|
||||||
|
import io.kamax.mxisd.exception.InternalServerError;
|
||||||
|
import io.kamax.mxisd.profile.ProfileProvider;
|
||||||
|
import org.apache.directory.api.ldap.model.cursor.CursorException;
|
||||||
|
import org.apache.directory.api.ldap.model.cursor.CursorLdapReferralException;
|
||||||
|
import org.apache.directory.api.ldap.model.cursor.EntryCursor;
|
||||||
|
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.message.SearchScope;
|
||||||
|
import org.apache.directory.ldap.client.api.LdapConnection;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LdapProfileProvider extends LdapBackend implements ProfileProvider {
|
||||||
|
|
||||||
|
private transient Logger log = LoggerFactory.getLogger(LdapProfileProvider.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LdapProfileProvider(LdapConfig cfg, MatrixConfig mxCfg) {
|
||||||
|
super(cfg, mxCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return getCfg().isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getDisplayName(_MatrixID userId) {
|
||||||
|
String uid = buildUidFromMatrixId(userId);
|
||||||
|
log.info("Searching for display name of {}:", uid);
|
||||||
|
|
||||||
|
try (LdapConnection conn = getConn()) {
|
||||||
|
bind(conn);
|
||||||
|
|
||||||
|
String searchQuery = buildOrQueryWithFilter(getCfg().getProfile().getFilter(), uid, getUidAtt());
|
||||||
|
|
||||||
|
log.debug("Base DN: {}", getBaseDn());
|
||||||
|
log.debug("Query: {}", searchQuery);
|
||||||
|
|
||||||
|
try (EntryCursor cursor = conn.search(getBaseDn(), searchQuery, SearchScope.SUBTREE, getAt().getName())) {
|
||||||
|
while (cursor.next()) {
|
||||||
|
Entry entry = cursor.get();
|
||||||
|
log.info("Found possible match, DN: {}", entry.getDn().getName());
|
||||||
|
Optional<String> v = getAttribute(entry, getAt().getName()).flatMap(id -> {
|
||||||
|
log.info("DN {} is a valid match", entry.getDn().getName());
|
||||||
|
try {
|
||||||
|
return getAttribute(entry, getAt().getName());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.warn("Bind was found but type {} is not supported", getAt().getUid().getType());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (v.isPresent()) {
|
||||||
|
log.info("DN {} is the final match", entry.getDn().getName());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CursorLdapReferralException e) {
|
||||||
|
log.warn("An entry is only available via referral, skipping");
|
||||||
|
} catch (IOException | LdapException | CursorException e) {
|
||||||
|
throw new InternalServerError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<_ThreePid> getThreepids(_MatrixID userId) {
|
||||||
|
String uid = buildUidFromMatrixId(userId);
|
||||||
|
log.info("Searching for 3PIDs of {}:", uid);
|
||||||
|
|
||||||
|
List<_ThreePid> threePids = new ArrayList<>();
|
||||||
|
try (LdapConnection conn = getConn()) {
|
||||||
|
bind(conn);
|
||||||
|
|
||||||
|
log.debug("Base DN: {}", getBaseDn());
|
||||||
|
getCfg().getAttribute().getThreepid().forEach((medium, attributes) -> {
|
||||||
|
String[] attArray = new String[attributes.size()];
|
||||||
|
attributes.toArray(attArray);
|
||||||
|
|
||||||
|
String searchQuery = buildOrQueryWithFilter(getCfg().getProfile().getFilter(), uid, getUidAtt());
|
||||||
|
|
||||||
|
log.debug("Query for 3PID {}: {}", medium, searchQuery);
|
||||||
|
|
||||||
|
try (EntryCursor cursor = conn.search(getBaseDn(), searchQuery, SearchScope.SUBTREE, attArray)) {
|
||||||
|
while (cursor.next()) {
|
||||||
|
Entry entry = cursor.get();
|
||||||
|
log.info("Found possible match, DN: {}", entry.getDn().getName());
|
||||||
|
try {
|
||||||
|
attributes.stream()
|
||||||
|
.flatMap(at -> getAttributes(entry, at).stream())
|
||||||
|
.forEach(address -> {
|
||||||
|
log.info("Found 3PID: {} - {}", medium, address);
|
||||||
|
threePids.add(new ThreePid(medium, address));
|
||||||
|
});
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.warn("Bind was found but type {} is not supported", getAt().getUid().getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CursorLdapReferralException e) {
|
||||||
|
log.warn("An entry is only available via referral, skipping");
|
||||||
|
} catch (IOException | LdapException | CursorException e) {
|
||||||
|
throw new InternalServerError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (IOException | LdapException e) {
|
||||||
|
throw new InternalServerError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return threePids;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRoles(_MatrixID userId) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.ldap.netiq;
|
||||||
|
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.mxisd.backend.ldap.LdapProfileProvider;
|
||||||
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
|
import io.kamax.mxisd.config.ldap.netiq.NetIqLdapConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class NetIqLdapProfileProvider extends LdapProfileProvider {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public NetIqLdapProfileProvider(NetIqLdapConfig cfg, MatrixConfig mxCfg) {
|
||||||
|
super(cfg, mxCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME this is duplicated in the other NetIQ classes, due to the Matrix ID generation code that was not abstracted
|
||||||
|
@Override
|
||||||
|
public String buildMatrixIdFromUid(String uid) {
|
||||||
|
return super.buildMatrixIdFromUid(uid).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME this is duplicated in the other NetIQ classes, due to the Matrix ID generation code that was not abstracted
|
||||||
|
@Override
|
||||||
|
public String buildUidFromMatrixId(_MatrixID mxid) {
|
||||||
|
return super.buildUidFromMatrixId(mxid).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2018 Maxime Dor
|
* Copyright (C) 2018 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://www.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
@@ -76,6 +76,11 @@ public class MemoryIdentityStore implements AuthenticatorProvider, IDirectoryPro
|
|||||||
return cfg.isEnabled();
|
return cfg.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getDisplayName(_MatrixID mxid) {
|
||||||
|
return findByUsername(mxid.getLocalPart()).map(MemoryIdentityConfig::getDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
private UserDirectorySearchResult search(
|
private UserDirectorySearchResult search(
|
||||||
Predicate<MemoryIdentityConfig> predicate,
|
Predicate<MemoryIdentityConfig> predicate,
|
||||||
Function<MemoryIdentityConfig, UserDirectorySearchResult.Result> mapper
|
Function<MemoryIdentityConfig, UserDirectorySearchResult.Result> mapper
|
||||||
@@ -143,7 +148,7 @@ public class MemoryIdentityStore implements AuthenticatorProvider, IDirectoryPro
|
|||||||
for (MemoryIdentityConfig id : cfg.getIdentities()) {
|
for (MemoryIdentityConfig id : cfg.getIdentities()) {
|
||||||
for (MemoryThreePid threepid : id.getThreepids()) {
|
for (MemoryThreePid threepid : id.getThreepids()) {
|
||||||
if (req.equals(new ThreePid(threepid.getMedium(), threepid.getAddress()))) {
|
if (req.equals(new ThreePid(threepid.getMedium(), threepid.getAddress()))) {
|
||||||
return Optional.of(new SingleLookupReply(request, new MatrixID(id.getUsername(), mxCfg.getDomain())));
|
return Optional.of(new SingleLookupReply(request, MatrixID.asAcceptable(id.getUsername(), mxCfg.getDomain())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package io.kamax.mxisd.backend.rest;
|
package io.kamax.mxisd.backend.rest;
|
||||||
|
|
||||||
|
import io.kamax.matrix.ThreePidMedium;
|
||||||
import io.kamax.mxisd.UserID;
|
import io.kamax.mxisd.UserID;
|
||||||
|
|
||||||
public class LookupSingleResponseJson {
|
public class LookupSingleResponseJson {
|
||||||
@@ -32,12 +33,28 @@ public class LookupSingleResponseJson {
|
|||||||
return medium;
|
return medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMedium(String medium) {
|
||||||
|
this.medium = medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedium(ThreePidMedium medium) {
|
||||||
|
setMedium(medium.getId());
|
||||||
|
}
|
||||||
|
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
public UserID getId() {
|
public UserID getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setId(UserID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -62,7 +62,7 @@ public class RestDirectoryProvider extends RestProvider implements IDirectoryPro
|
|||||||
|
|
||||||
UserDirectorySearchResult response = parser.parse(httpResponse, UserDirectorySearchResult.class);
|
UserDirectorySearchResult response = parser.parse(httpResponse, UserDirectorySearchResult.class);
|
||||||
for (UserDirectorySearchResult.Result result : response.getResults()) {
|
for (UserDirectorySearchResult.Result result : response.getResults()) {
|
||||||
result.setUserId(new MatrixID(result.getUserId(), mxCfg.getDomain()).getId());
|
result.setUserId(MatrixID.asAcceptable(result.getUserId(), mxCfg.getDomain()).getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -60,9 +60,9 @@ public class RestThreePidProvider extends RestProvider implements IThreePidProvi
|
|||||||
// TODO refactor in lookup manager with above FIXME
|
// TODO refactor in lookup manager with above FIXME
|
||||||
private _MatrixID getMxId(UserID id) {
|
private _MatrixID getMxId(UserID id) {
|
||||||
if (UserIdType.Localpart.is(id.getType())) {
|
if (UserIdType.Localpart.is(id.getType())) {
|
||||||
return new MatrixID(id.getValue(), mxCfg.getDomain());
|
return MatrixID.asAcceptable(id.getValue(), mxCfg.getDomain());
|
||||||
} else {
|
} else {
|
||||||
return new MatrixID(id.getValue());
|
return MatrixID.asAcceptable(id.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -28,6 +28,12 @@ import java.sql.SQLException;
|
|||||||
|
|
||||||
public class SqlConnectionPool {
|
public class SqlConnectionPool {
|
||||||
|
|
||||||
|
public interface SqlFunction<T, R> {
|
||||||
|
|
||||||
|
R run(T connection) throws SQLException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private ComboPooledDataSource ds;
|
private ComboPooledDataSource ds;
|
||||||
|
|
||||||
public SqlConnectionPool(SqlConfig cfg) {
|
public SqlConnectionPool(SqlConfig cfg) {
|
||||||
@@ -42,4 +48,12 @@ public class SqlConnectionPool {
|
|||||||
return ds.getConnection();
|
return ds.getConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> T withConnFunction(SqlFunction<Connection, T> function) {
|
||||||
|
try (Connection conn = get()) {
|
||||||
|
return function.run(conn);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
105
src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java
Normal file
105
src/main/java/io/kamax/mxisd/backend/sql/SqlProfileProvider.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql;
|
||||||
|
|
||||||
|
import io.kamax.matrix.ThreePid;
|
||||||
|
import io.kamax.matrix._MatrixID;
|
||||||
|
import io.kamax.matrix._ThreePid;
|
||||||
|
import io.kamax.mxisd.config.sql.SqlConfig;
|
||||||
|
import io.kamax.mxisd.profile.ProfileProvider;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public abstract class SqlProfileProvider implements ProfileProvider {
|
||||||
|
|
||||||
|
private Logger log = LoggerFactory.getLogger(SqlProfileProvider.class);
|
||||||
|
|
||||||
|
private SqlConfig.Profile cfg;
|
||||||
|
|
||||||
|
private SqlConnectionPool pool;
|
||||||
|
|
||||||
|
public SqlProfileProvider(SqlConfig cfg) {
|
||||||
|
this.cfg = cfg.getProfile();
|
||||||
|
this.pool = new SqlConnectionPool(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return cfg.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getDisplayName(_MatrixID user) {
|
||||||
|
String stmtSql = cfg.getDisplayName().getQuery();
|
||||||
|
try (Connection conn = pool.get()) {
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(stmtSql)) {
|
||||||
|
stmt.setString(1, user.getId());
|
||||||
|
|
||||||
|
try (ResultSet rSet = stmt.executeQuery()) {
|
||||||
|
if (!rSet.next()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.ofNullable(rSet.getString(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<_ThreePid> getThreepids(_MatrixID user) {
|
||||||
|
List<_ThreePid> threepids = new ArrayList<>();
|
||||||
|
|
||||||
|
String stmtSql = cfg.getThreepid().getQuery();
|
||||||
|
try (Connection conn = pool.get()) {
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(stmtSql);
|
||||||
|
stmt.setString(1, user.getId());
|
||||||
|
|
||||||
|
ResultSet rSet = stmt.executeQuery();
|
||||||
|
while (rSet.next()) {
|
||||||
|
String medium = rSet.getString(1);
|
||||||
|
String address = rSet.getString(2);
|
||||||
|
threepids.add(new ThreePid(medium, address));
|
||||||
|
}
|
||||||
|
|
||||||
|
return threepids;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRoles(_MatrixID user) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -21,16 +21,12 @@
|
|||||||
package io.kamax.mxisd.backend.sql;
|
package io.kamax.mxisd.backend.sql;
|
||||||
|
|
||||||
import io.kamax.matrix.MatrixID;
|
import io.kamax.matrix.MatrixID;
|
||||||
import io.kamax.matrix.ThreePid;
|
|
||||||
import io.kamax.matrix._MatrixID;
|
|
||||||
import io.kamax.matrix._ThreePid;
|
|
||||||
import io.kamax.mxisd.config.MatrixConfig;
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
import io.kamax.mxisd.config.sql.SqlConfig;
|
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;
|
||||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||||
import io.kamax.mxisd.profile.ProfileProvider;
|
|
||||||
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;
|
||||||
@@ -40,11 +36,10 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class SqlThreePidProvider implements IThreePidProvider, ProfileProvider {
|
public abstract class SqlThreePidProvider implements IThreePidProvider {
|
||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class);
|
private Logger log = LoggerFactory.getLogger(SqlThreePidProvider.class);
|
||||||
|
|
||||||
@@ -90,11 +85,11 @@ public abstract class SqlThreePidProvider implements IThreePidProvider, ProfileP
|
|||||||
log.info("Found match: {}", uid);
|
log.info("Found match: {}", uid);
|
||||||
if (StringUtils.equals("uid", cfg.getIdentity().getType())) {
|
if (StringUtils.equals("uid", cfg.getIdentity().getType())) {
|
||||||
log.info("Resolving as localpart");
|
log.info("Resolving as localpart");
|
||||||
return Optional.of(new SingleLookupReply(request, new MatrixID(uid, mxCfg.getDomain())));
|
return Optional.of(new SingleLookupReply(request, MatrixID.asAcceptable(uid, mxCfg.getDomain())));
|
||||||
}
|
}
|
||||||
if (StringUtils.equals("mxid", cfg.getIdentity().getType())) {
|
if (StringUtils.equals("mxid", cfg.getIdentity().getType())) {
|
||||||
log.info("Resolving as MXID");
|
log.info("Resolving as MXID");
|
||||||
return Optional.of(new SingleLookupReply(request, new MatrixID(uid)));
|
return Optional.of(new SingleLookupReply(request, MatrixID.asAcceptable(uid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Identity type is unknown, skipping");
|
log.info("Identity type is unknown, skipping");
|
||||||
@@ -114,31 +109,4 @@ public abstract class SqlThreePidProvider implements IThreePidProvider, ProfileP
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<_ThreePid> getThreepids(_MatrixID mxid) {
|
|
||||||
List<_ThreePid> threepids = new ArrayList<>();
|
|
||||||
|
|
||||||
String stmtSql = cfg.getProfile().getThreepid().getQuery();
|
|
||||||
try (Connection conn = pool.get()) {
|
|
||||||
PreparedStatement stmt = conn.prepareStatement(stmtSql);
|
|
||||||
stmt.setString(1, mxid.getId());
|
|
||||||
|
|
||||||
ResultSet rSet = stmt.executeQuery();
|
|
||||||
while (rSet.next()) {
|
|
||||||
String medium = rSet.getString("medium");
|
|
||||||
String address = rSet.getString("address");
|
|
||||||
threepids.add(new ThreePid(medium, address));
|
|
||||||
}
|
|
||||||
|
|
||||||
return threepids;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getRoles(_MatrixID mxid) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
|
||||||
import io.kamax.mxisd.exception.ConfigurationException;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class SynapseSqlDirectoryProvider extends GenericSqlDirectoryProvider {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SynapseSqlDirectoryProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) {
|
|
||||||
super(cfg, mxCfg);
|
|
||||||
|
|
||||||
if (StringUtils.equals("sqlite", cfg.getType())) {
|
|
||||||
String userId = "'@' || p.user_id || ':" + mxCfg.getDomain() + "'";
|
|
||||||
GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery();
|
|
||||||
queries.getName().setValue(
|
|
||||||
"select " + userId + ", displayname from profiles p where displayname like ?");
|
|
||||||
queries.getThreepid().setValue(
|
|
||||||
"select t.user_id, p.displayname " +
|
|
||||||
"from user_threepids t JOIN profiles p on t.user_id = " + userId + " " +
|
|
||||||
"where t.address like ?");
|
|
||||||
} else if (StringUtils.equals("postgresql", cfg.getType())) {
|
|
||||||
String userId = "concat('@',p.user_id,':" + mxCfg.getDomain() + "')";
|
|
||||||
GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery();
|
|
||||||
queries.getName().setValue(
|
|
||||||
"select " + userId + ", displayname from profiles p where displayname ilike ?");
|
|
||||||
queries.getThreepid().setValue(
|
|
||||||
"select t.user_id, p.displayname " +
|
|
||||||
"from user_threepids t JOIN profiles p on t.user_id = " + userId + " " +
|
|
||||||
"where t.address ilike ?");
|
|
||||||
} else {
|
|
||||||
throw new ConfigurationException("Invalid SQL type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
|
|
||||||
stmt.setString(1, "%" + searchTerm + "%");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,13 +18,12 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.backend.sql;
|
package io.kamax.mxisd.backend.sql.generic;
|
||||||
|
|
||||||
import io.kamax.matrix._MatrixID;
|
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.sql.generic.GenericSqlProviderConfig;
|
||||||
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;
|
||||||
@@ -36,9 +35,6 @@ public class GenericSqlAuthProvider implements AuthenticatorProvider {
|
|||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger(GenericSqlAuthProvider.class);
|
private Logger log = LoggerFactory.getLogger(GenericSqlAuthProvider.class);
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ServerConfig srvCfg;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private GenericSqlProviderConfig cfg;
|
private GenericSqlProviderConfig cfg;
|
||||||
|
|
||||||
@@ -47,7 +43,7 @@ public class GenericSqlAuthProvider implements AuthenticatorProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return cfg.isEnabled();
|
return cfg.getAuth().isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,12 +18,13 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.backend.sql;
|
package io.kamax.mxisd.backend.sql.generic;
|
||||||
|
|
||||||
import io.kamax.matrix.MatrixID;
|
import io.kamax.matrix.MatrixID;
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlConnectionPool;
|
||||||
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.generic.GenericSqlProviderConfig;
|
||||||
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;
|
||||||
@@ -44,7 +45,7 @@ public abstract class GenericSqlDirectoryProvider implements IDirectoryProvider
|
|||||||
private Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class);
|
private Logger log = LoggerFactory.getLogger(GenericSqlDirectoryProvider.class);
|
||||||
|
|
||||||
protected SqlConfig cfg;
|
protected SqlConfig cfg;
|
||||||
private MatrixConfig mxCfg;
|
protected MatrixConfig mxCfg;
|
||||||
|
|
||||||
private SqlConnectionPool pool;
|
private SqlConnectionPool pool;
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ public abstract class GenericSqlDirectoryProvider implements IDirectoryProvider
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return cfg.isEnabled();
|
return cfg.getDirectory().isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
|
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
|
||||||
@@ -85,7 +86,7 @@ public abstract class GenericSqlDirectoryProvider implements IDirectoryProvider
|
|||||||
while (rSet.next()) {
|
while (rSet.next()) {
|
||||||
processRow(rSet).ifPresent(e -> {
|
processRow(rSet).ifPresent(e -> {
|
||||||
if (StringUtils.equalsIgnoreCase("localpart", query.getType())) {
|
if (StringUtils.equalsIgnoreCase("localpart", query.getType())) {
|
||||||
e.setUserId(new MatrixID(e.getUserId(), mxCfg.getDomain()).getId());
|
e.setUserId(MatrixID.asAcceptable(e.getUserId(), mxCfg.getDomain()).getId());
|
||||||
}
|
}
|
||||||
result.addResult(e);
|
result.addResult(e);
|
||||||
});
|
});
|
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql.generic;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlProfileProvider;
|
||||||
|
import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class GenericSqlProfileProvider extends SqlProfileProvider {
|
||||||
|
|
||||||
|
public GenericSqlProfileProvider(GenericSqlProviderConfig cfg) {
|
||||||
|
super(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,10 +18,11 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.backend.sql;
|
package io.kamax.mxisd.backend.sql.generic;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlThreePidProvider;
|
||||||
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.generic.GenericSqlProviderConfig;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql.synapse;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlConnectionPool;
|
||||||
|
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Synapse {
|
||||||
|
|
||||||
|
private SqlConnectionPool pool;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public Synapse(SynapseSqlProviderConfig sqlCfg) {
|
||||||
|
this.pool = new SqlConnectionPool(sqlCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getRoomName(String id) {
|
||||||
|
return pool.withConnFunction(conn -> {
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(SynapseQueries.getRoomName());
|
||||||
|
stmt.setString(1, id);
|
||||||
|
ResultSet rSet = stmt.executeQuery();
|
||||||
|
if (!rSet.next()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.ofNullable(rSet.getString(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql.synapse;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.exception.ConfigurationException;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
public class SynapseQueries {
|
||||||
|
|
||||||
|
public static String getUserId(String type, String domain) {
|
||||||
|
if (StringUtils.equals("sqlite", type)) {
|
||||||
|
return "'@' || p.user_id || ':" + domain + "'";
|
||||||
|
} else if (StringUtils.equals("postgresql", type)) {
|
||||||
|
return "concat('@',p.user_id,':" + domain + "')";
|
||||||
|
} else {
|
||||||
|
throw new ConfigurationException("Invalid Synapse SQL type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDisplayName() {
|
||||||
|
return "SELECT displayname FROM profiles WHERE user_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getThreepids() {
|
||||||
|
return "SELECT medium, address FROM user_threepids WHERE user_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String findByDisplayName(String type, String domain) {
|
||||||
|
if (StringUtils.equals("sqlite", type)) {
|
||||||
|
return "select " + getUserId(type, domain) + ", displayname from profiles p where displayname like ?";
|
||||||
|
} else if (StringUtils.equals("postgresql", type)) {
|
||||||
|
return "select " + getUserId(type, domain) + ", displayname from profiles p where displayname ilike ?";
|
||||||
|
} else {
|
||||||
|
throw new ConfigurationException("Invalid Synapse SQL type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String findByThreePidAddress(String type, String domain) {
|
||||||
|
if (StringUtils.equals("sqlite", type)) {
|
||||||
|
return "select t.user_id, p.displayname " +
|
||||||
|
"from user_threepids t JOIN profiles p on t.user_id = " + getUserId(type, domain) + " " +
|
||||||
|
"where t.address like ?";
|
||||||
|
} else if (StringUtils.equals("postgresql", type)) {
|
||||||
|
return "select t.user_id, p.displayname " +
|
||||||
|
"from user_threepids t JOIN profiles p on t.user_id = " + getUserId(type, domain) + " " +
|
||||||
|
"where t.address ilike ?";
|
||||||
|
} else {
|
||||||
|
throw new ConfigurationException("Invalid Synapse SQL type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRoomName() {
|
||||||
|
return "select r.name from room_names r, events e, (select r1.room_id,max(e1.origin_server_ts) ts from room_names r1, events e1 where r1.event_id = e1.event_id group by r1.room_id) rle where e.origin_server_ts = rle.ts and r.event_id = e.event_id and r.room_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql.synapse;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.generic.GenericSqlDirectoryProvider;
|
||||||
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
|
import io.kamax.mxisd.config.sql.generic.GenericSqlProviderConfig;
|
||||||
|
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SynapseSqlDirectoryProvider extends GenericSqlDirectoryProvider {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SynapseSqlDirectoryProvider(SynapseSqlProviderConfig cfg, MatrixConfig mxCfg) {
|
||||||
|
super(cfg, mxCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setParameters(PreparedStatement stmt, String searchTerm) throws SQLException {
|
||||||
|
stmt.setString(1, "%" + searchTerm + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void build() {
|
||||||
|
if (!isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericSqlProviderConfig.Type queries = cfg.getDirectory().getQuery();
|
||||||
|
if (Objects.isNull(queries.getName().getValue())) {
|
||||||
|
queries.getName().setValue(SynapseQueries.findByDisplayName(cfg.getType(), mxCfg.getDomain()));
|
||||||
|
}
|
||||||
|
if (Objects.isNull(queries.getThreepid().getValue())) {
|
||||||
|
queries.getThreepid().setValue(SynapseQueries.findByThreePidAddress(cfg.getType(), mxCfg.getDomain()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.backend.sql.synapse;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlProfileProvider;
|
||||||
|
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SynapseSqlProfileProvider extends SqlProfileProvider {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SynapseSqlProfileProvider(SynapseSqlProviderConfig cfg) {
|
||||||
|
super(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.kamax.mxisd.backend.sql;
|
package io.kamax.mxisd.backend.sql.synapse;
|
||||||
|
|
||||||
|
import io.kamax.mxisd.backend.sql.SqlThreePidProvider;
|
||||||
import io.kamax.mxisd.config.MatrixConfig;
|
import io.kamax.mxisd.config.MatrixConfig;
|
||||||
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
import io.kamax.mxisd.config.sql.synapse.SynapseSqlProviderConfig;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
51
src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java
Normal file
51
src/main/java/io/kamax/mxisd/config/BulkLookupConfig.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "lookup.bulk")
|
||||||
|
public class BulkLookupConfig {
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
public Boolean getEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void build() {
|
||||||
|
if (Objects.isNull(enabled)) {
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -25,6 +25,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
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;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties("directory")
|
@ConfigurationProperties("directory")
|
||||||
public class DirectoryConfig {
|
public class DirectoryConfig {
|
||||||
@@ -34,6 +36,7 @@ public class DirectoryConfig {
|
|||||||
public static class Exclude {
|
public static class Exclude {
|
||||||
|
|
||||||
private boolean homeserver;
|
private boolean homeserver;
|
||||||
|
private boolean threepid;
|
||||||
|
|
||||||
public boolean getHomeserver() {
|
public boolean getHomeserver() {
|
||||||
return homeserver;
|
return homeserver;
|
||||||
@@ -44,6 +47,14 @@ public class DirectoryConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getThreepid() {
|
||||||
|
return threepid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThreepid(boolean threepid) {
|
||||||
|
this.threepid = threepid;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Exclude exclude = new Exclude();
|
private Exclude exclude = new Exclude();
|
||||||
@@ -56,4 +67,12 @@ public class DirectoryConfig {
|
|||||||
this.exclude = exclude;
|
this.exclude = exclude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void buid() {
|
||||||
|
log.info("--- Directory config ---");
|
||||||
|
log.info("Exclude:");
|
||||||
|
log.info("\tHomeserver: {}", getExclude().getHomeserver());
|
||||||
|
log.info("\t3PID: {}", getExclude().getThreepid());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
540
src/main/java/io/kamax/mxisd/config/ExecConfig.java
Normal file
540
src/main/java/io/kamax/mxisd/config/ExecConfig.java
Normal file
@@ -0,0 +1,540 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.config;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties("exec")
|
||||||
|
public class ExecConfig {
|
||||||
|
|
||||||
|
public class IO {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String template;
|
||||||
|
|
||||||
|
public Optional<String> getType() {
|
||||||
|
return Optional.ofNullable(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getTemplate() {
|
||||||
|
return Optional.ofNullable(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemplate(String template) {
|
||||||
|
this.template = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Exit {
|
||||||
|
|
||||||
|
private List<Integer> success = Collections.singletonList(0);
|
||||||
|
private List<Integer> failure = Collections.singletonList(1);
|
||||||
|
|
||||||
|
public List<Integer> getSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccess(List<Integer> success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getFailure() {
|
||||||
|
return failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailure(List<Integer> failure) {
|
||||||
|
this.failure = failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TokenOverride {
|
||||||
|
|
||||||
|
private String localpart;
|
||||||
|
private String domain;
|
||||||
|
private String mxid;
|
||||||
|
private String password;
|
||||||
|
private String medium;
|
||||||
|
private String address;
|
||||||
|
private String type;
|
||||||
|
private String query;
|
||||||
|
|
||||||
|
public String getLocalpart() {
|
||||||
|
return StringUtils.defaultIfEmpty(localpart, getToken().getLocalpart());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalpart(String localpart) {
|
||||||
|
this.localpart = localpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return StringUtils.defaultIfEmpty(domain, getToken().getDomain());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMxid() {
|
||||||
|
return StringUtils.defaultIfEmpty(mxid, getToken().getMxid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMxid(String mxid) {
|
||||||
|
this.mxid = mxid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return StringUtils.defaultIfEmpty(password, getToken().getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMedium() {
|
||||||
|
return StringUtils.defaultIfEmpty(medium, getToken().getMedium());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedium(String medium) {
|
||||||
|
this.medium = medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return StringUtils.defaultIfEmpty(address, getToken().getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return StringUtils.defaultIfEmpty(type, getToken().getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return StringUtils.defaultIfEmpty(query, getToken().getQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Token {
|
||||||
|
|
||||||
|
private String localpart = "{localpart}";
|
||||||
|
private String domain = "{domain}";
|
||||||
|
private String mxid = "{mxid}";
|
||||||
|
private String password = "{password}";
|
||||||
|
private String medium = "{medium}";
|
||||||
|
private String address = "{address}";
|
||||||
|
private String type = "{type}";
|
||||||
|
private String query = "{query}";
|
||||||
|
|
||||||
|
public String getLocalpart() {
|
||||||
|
return localpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalpart(String localpart) {
|
||||||
|
this.localpart = localpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMxid() {
|
||||||
|
return mxid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMxid(String mxid) {
|
||||||
|
this.mxid = mxid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMedium() {
|
||||||
|
return medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedium(String medium) {
|
||||||
|
this.medium = medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Process {
|
||||||
|
|
||||||
|
private TokenOverride token = new TokenOverride();
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
private List<String> args = new ArrayList<>();
|
||||||
|
private Map<String, String> env = new HashMap<>();
|
||||||
|
private IO input = new IO();
|
||||||
|
|
||||||
|
private Exit exit = new Exit();
|
||||||
|
private IO output = new IO();
|
||||||
|
|
||||||
|
public TokenOverride getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(TokenOverride token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArgs(List<String> args) {
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getEnv() {
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnv(Map<String, String> env) {
|
||||||
|
this.env = env;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEnv(String key, String value) {
|
||||||
|
this.env.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IO getInput() {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInput(IO input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exit getExit() {
|
||||||
|
return exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExit(Exit exit) {
|
||||||
|
this.exit = exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IO getOutput() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(IO output) {
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Auth extends Process {
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Directory {
|
||||||
|
|
||||||
|
public class Search {
|
||||||
|
|
||||||
|
private Process byName = new Process();
|
||||||
|
private Process byThreepid = new Process();
|
||||||
|
|
||||||
|
public Process getByName() {
|
||||||
|
return byName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByName(Process byName) {
|
||||||
|
this.byName = byName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getByThreepid() {
|
||||||
|
return byThreepid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByThreepid(Process byThreepid) {
|
||||||
|
this.byThreepid = byThreepid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
private Search search = new Search();
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Search getSearch() {
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearch(Search search) {
|
||||||
|
this.search = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Lookup {
|
||||||
|
|
||||||
|
private Process single = new Process();
|
||||||
|
private Process bulk = new Process();
|
||||||
|
|
||||||
|
public Process getSingle() {
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSingle(Process single) {
|
||||||
|
this.single = single;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getBulk() {
|
||||||
|
return bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBulk(Process bulk) {
|
||||||
|
this.bulk = bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Identity {
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
private int priority;
|
||||||
|
private Lookup lookup = new Lookup();
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lookup getLookup() {
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLookup(Lookup lookup) {
|
||||||
|
this.lookup = lookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Profile {
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
private Process displayName = new Process();
|
||||||
|
private Process threePid = new Process();
|
||||||
|
private Process role = new Process();
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(Process displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getThreePid() {
|
||||||
|
return threePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThreePid(Process threePid) {
|
||||||
|
this.threePid = threePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(Process role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
private Token token = new Token();
|
||||||
|
private Auth auth = new Auth();
|
||||||
|
private Directory directory = new Directory();
|
||||||
|
private Identity identity = new Identity();
|
||||||
|
private Profile profile = new Profile();
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Token getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(Token token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Auth getAuth() {
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuth(Auth auth) {
|
||||||
|
this.auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Directory getDirectory() {
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectory(Directory directory) {
|
||||||
|
this.directory = directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identity getIdentity() {
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentity(Identity identity) {
|
||||||
|
this.identity = identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Profile getProfile() {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfile(Profile profile) {
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public ExecConfig compute() {
|
||||||
|
if (Objects.isNull(getAuth().isEnabled())) {
|
||||||
|
getAuth().setEnabled(isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(getDirectory().isEnabled())) {
|
||||||
|
getDirectory().setEnabled(isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(getIdentity().isEnabled())) {
|
||||||
|
getIdentity().setEnabled(isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(getProfile().isEnabled())) {
|
||||||
|
getProfile().setEnabled(isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* mxisd - Matrix Identity Server Daemon
|
* mxisd - Matrix Identity Server Daemon
|
||||||
* Copyright (C) 2017 Maxime Dor
|
* Copyright (C) 2017 Kamax Sarl
|
||||||
*
|
*
|
||||||
* https://max.kamax.io/
|
* https://www.kamax.io/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
108
src/main/java/io/kamax/mxisd/config/ListenerConfig.java
Normal file
108
src/main/java/io/kamax/mxisd/config/ListenerConfig.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* mxisd - Matrix Identity Server Daemon
|
||||||
|
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.kamax.mxisd.config;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties("matrix.listener")
|
||||||
|
public class ListenerConfig {
|
||||||
|
|
||||||
|
public static class Token {
|
||||||
|
|
||||||
|
private String as;
|
||||||
|
private String hs;
|
||||||
|
|
||||||
|
public String getAs() {
|
||||||
|
return as;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAs(String as) {
|
||||||
|
this.as = as;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHs() {
|
||||||
|
return hs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHs(String hs) {
|
||||||
|
this.hs = hs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private transient URL csUrl;
|
||||||
|
private String url;
|
||||||
|
private String localpart;
|
||||||
|
private Token token = new Token();
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
return csUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalpart() {
|
||||||
|
return localpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalpart(String localpart) {
|
||||||
|
this.localpart = localpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Token getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(Token token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void build() throws MalformedURLException {
|
||||||
|
if (StringUtils.isBlank(url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
csUrl = new URL(url);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(getLocalpart())) {
|
||||||
|
throw new IllegalArgumentException("localpart for matrix listener is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(getToken().getAs())) {
|
||||||
|
throw new IllegalArgumentException("AS token is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(getToken().getHs())) {
|
||||||
|
throw new IllegalArgumentException("HS token is not set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user