Git Product home page Git Product logo

matrix-synapse-rest-password-provider's Introduction

Synapse REST Password provider


This project is no longer maintained.


Overview

This synapse's password provider allows you to validate a password for a given username and return a user profile using an existing backend, like:

  • Forums (phpBB, Discourse, etc.)
  • Custom Identity stores (Keycloak, ...)
  • CRMs (Wordpress, ...)
  • self-hosted clouds (Nextcloud, ownCloud, ...)

It is mainly used with mxisd, the Federated Matrix Identity Server, to provide missing features and offer a fully integrated solution (directory, authentication, search).

NOTE: This module doesn't provide direct integration with any backend. If you do not use mxisd, you will need to write your own backend, following the Integration section. This module simply translate an anthentication result and profile information into actionables in synapse, and adapt your user profile with what is given.

Install

From Synapse v0.34.0/py3

Copy in whichever directory python3.x can pick it up as a module.

If you installed synapse using the Matrix debian repos:

sudo curl https://raw.githubusercontent.com/kamax-matrix/matrix-synapse-rest-auth/master/rest_auth_provider.py -o /opt/venvs/matrix-synapse/lib/python3.5/site-packages/rest_auth_provider.py

If the command fail, double check that the python version still matches. If not, please let us know by opening an issue.

Before Synapse v0.34.0/py3 or any py2-based release

Copy in whichever directory python2.x can pick it up as a module.

If you installed synapse using the Matrix debian repos:

sudo curl https://raw.githubusercontent.com/kamax-matrix/matrix-synapse-rest-auth/master/rest_auth_provider.py -o /usr/lib/python2.7/dist-packages/rest_auth_provider.py

If the command fail, double check that the python version still matches. If not, please let us know by opening an issue.

Configure

Add or amend the password_providers entry like so:

password_providers:
  - module: "rest_auth_provider.RestAuthProvider"
    config:
      endpoint: "http://change.me.example.com:12345"

Set endpoint to the value documented with the endpoint provider.

Use

  1. Install, configure, restart synapse
  2. Try to login with a valid username and password for the endpoint configured

Next steps

Lowercase username enforcement

NOTE: This is no longer relevant as synapse natively enforces lowercase.

To avoid creating users accounts with uppercase characters in their usernames and running into known issues regarding case sensitivity in synapse, attempting to login with such username will fail.

It is highly recommended to keep this feature enable, but in case you would like to disable it:

    config:
      policy:
        registration:
          username:
            enforceLowercase: false

Profile auto-fill

By default, on first login, the display name is set to the one returned by the backend.
If none is given, the display name is not set.
Upon subsequent login, the display name is not changed.

If you would like to change the behaviour, you can use the following configuration items:

    config:
      policy:
        registration:
          profile:
            name: true
        login:
          profile:
            name: false

3PIDs received from the backend are merged with the ones already linked to the account. If you would like to change this behaviour, you can use the following configuration items:

    config:
      policy:
        all:
          threepid:
            update: false
            replace: false

If update is set to false, the 3PIDs will not be changed at all. If replace is set to true, all 3PIDs not available in the backend anymore will be deleted from synapse.

Integrate

To use this module with your back-end, you will need to implement a single REST endpoint:

Path: /_matrix-internal/identity/v1/check_credentials
Method: POST
Body as JSON UTF-8:

{
  "user": {
    "id": "@matrix.id.of.the.user:example.com",
    "password": "passwordOfTheUser"
  }
}

If the credentials are accepted, the following JSON answer will be provided:

{
  "auth": {
    "success": true,
    "mxid": "@matrix.id.of.the.user:example.com",
    "profile": {
      "display_name": "John Doe",
      "three_pids": [
        {
          "medium": "email",
          "address": "[email protected]"
        },
        {
          "medium": "msisdn",
          "address": "123456789"
        }
      ]
    }
  }
}

auth.profile and any sub-key are optional.


If the credentials are refused, the following JSON answer will be provided:

{
  "auth": {
    "success": false
  }
}

matrix-synapse-rest-password-provider's People

Contributors

maxidorius avatar peerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

matrix-synapse-rest-password-provider's Issues

POST updated to GET by Synapse ?

Hi,

I'm trying to use this auth provider but it doesn't seem to work. I'm using the master branch of synapse inside a Docker container. It looks like https://github.com/kamax-io/matrix-synapse-rest-auth/blob/master/rest_auth_provider.py#L47 request is updated by Synapse ? (mxisd complains about a GET request while it's a POST request, and so it results in an error 405)

Thanks

synapse_1 | 2017-10-06 19:46:04,536 - synapse.access.http.8008 - 59 - INFO - POST-0- 172.18.0.22 - 8008 - Received request: POST /_matrix/client/r0/login?
synapse_1 | 2017-10-06 19:46:04,537 - rest_auth_provider - 45 - INFO - POST-0- Got password check for @myusername:matrix.example.com
mxisd_1 | 2017-10-06 19:46:04.873 WARN [nio-8090-exec-1] o.s.web.servlet.PageNotFound : Request method 'GET' not supported
synapse_1 | 2017-10-06 19:46:05,099 - synapse.http.server - 139 - ERROR - POST-0- Failed handle request synapse.http.server._async_render on <synapse.rest.ClientRestResource object at 0x7f68f8004750>: <SynapseRequest at 0x7f68f7fd0c68 method=POST uri=/_matrix/client/r0/login? clientproto=HTTP/1.0 site=8008>
synapse_1 | Traceback (most recent call last):
synapse_1 | File "/usr/local/lib/python2.7/dist-packages/synapse/http/server.py", line 116, in wrapped_request_handler
synapse_1 | yield request_handler(self, request, request_metrics)
synapse_1 | HTTPError: 405 Client Error: for url: https://matrix.example.com/_matrix-internal/identity/v1/check_credentials
synapse_1 | 2017-10-06 19:46:05,102 - synapse.access.http.8008 - 91 - INFO - POST-0- 172.18.0.22 - 8008 - {None} Processed request: 565ms (43ms, 4ms) (0ms/0) 67B 500 "POST /_matrix/client/r0/login? HTTP/1.0" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Riot/0.12.4 Chrome/58.0.3029.110 Electron/1.7.5 Safari/537.36"

Silent failure on bad endpoint?

While testing the behavior of the provider, I accidentally stumbled upon a silent failure (synapse 0.99.3 on ubuntu 18.04), when the endpoint doesnt serve an expected response. The configuration for pw providers is

password_providers:
  - module: "shared_secret_authenticator.SharedSecretAuthenticator"
    config:
      sharedSecret: iitruitrrtriutrietoieruto
  - module: "rest_auth_provider.RestAuthProvider"
    config:
      endpoint: https://example.com/
      policy:
        registration:
          username:
            enforceLowercase: False
          profile:
            name: True
        login:
          profile:
            name: False

that for logging

loggers:
    synapse:
        level: INFO
    synapse.storage.SQL:
        level: INFO
    rest_auth_provider:
        level: INFO
        handlers: [file, console]
    shared_secret_authenticator:
        level: INFO
        handlers: [file, console]

While logging in, I get:

/opt/venvs/matrix-synapse/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-synapse/homeserver.yaml --config-path=/etc/matrix-synapse/conf.d/
2019-04-19 21:10:14,168 - root - 211 - WARNING - None- ***** STARTING SERVER *****
2019-04-19 21:10:14,178 - root - 214 - WARNING - None- Server /opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/app/homeserver.py version 0.99.3
2019-04-19 21:10:14,187 - twisted - 242 - WARNING - None- /opt/venvs/matrix-synapse/lib/python3.6/site-packages/psycopg2/__init__.py:144: builtins.UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
2019-04-19 21:12:14,247 - synapse.storage._base - 401 - WARNING - - Starting db txn 'update_presence' from sentinel context
2019-04-19 21:12:14,247 - synapse.storage._base - 437 - WARNING - - Starting db connection from sentinel context: metrics will be lost
2019-04-19 21:13:05,805 - synapse.http.server - 112 - ERROR - POST-53- Failed handle request via 'LoginRestServlet': <XForwardedForRequest at 0x7f24d441b128 method='POST' uri='/_matrix/client/r0/login' clientproto='HTTP/1.1' site=8008>
Traceback (most recent call last):
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/http/server.py", line 81, in wrapped_request_handler
    yield h(self, request)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/http/server.py", line 316, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/rest/client/v1/login.py", line 149, in on_POST
    result = yield self._do_other_login(login_submission)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/rest/client/v1/login.py", line 246, in _do_other_login
    login_submission,
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/synapse/handlers/auth.py", line 679, in validate_login
    qualified_user_id, password,
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/rest_auth_provider.py", line 50, in check_password
    r = r.json()
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/simplejson/__init__.py", line 518, in loads
    return _default_decoder.decode(s)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/opt/venvs/matrix-synapse/lib/python3.6/site-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
^C2019-04-19 21:13:12,347 - synapse.storage._base - 401 - WARNING - - Starting db txn 'update_presence' from sentinel context
2019-04-19 21:13:12,348 - synapse.storage._base - 437 - WARNING - - Starting db connection from sentinel context: metrics will be lost
2019-04-19 21:13:12,363 - synapse.http.site - 203 - WARNING - GET-48- Error processing request <XForwardedForRequest at 0x7f24d441f2e8 method='GET' uri='/_matrix/client/r0/sync?filter=0&timeout=30000&since=s52_3700_0_6_24_1_1_33_1' clientproto='HTTP/1.1' site=8008>: <class 'twisted.internet.error.ConnectionLost'> Connection to the other side was lost in a non-clean fashion: Connection lost.
2019-04-19 21:13:12,364 - synapse.http.site - 203 - WARNING - GET-50- Error processing request <XForwardedForRequest at 0x7f24d43d37f0 method='GET' uri='/_matrix/client/r0/sync?filter=%7B%7D&timeout=30000&since=s52_3700_0_6_24_1_1_33_1' clientproto='HTTP/1.1' site=8008>: <class 'twisted.internet.error.ConnectionLost'> Connection to the other side was lost in a non-clean fashion: Connection lost.
2019-04-19 21:13:12,365 - synapse.http.site - 203 - WARNING - GET-47- Error processing request <XForwardedForRequest at 0x7f24da7b5f28 method='GET' uri='/_matrix/client/r0/sync?filter=0&timeout=30000&since=s52_3700_0_6_24_1_1_33_1' clientproto='HTTP/1.1' site=8008>: <class 'twisted.internet.error.ConnectionLost'> Connection to the other side was lost in a non-clean fashion: Connection lost.

Would you mind trying if you can reproduce this?

In check_password #51: TypeError: list indices must be integers or slices, not str

I am getting the following error in the log file:

2019-04-23 15:46:31,940 - synapse.http.server - 112 - ERROR - POST-8 - Failed handle request via 'LoginRestServlet': <XForwardedForRequest at 0x7f2888f2ce48 method='POST' uri='/_matrix/client/r0/login' clientproto='HTTP/1.1' site=8008>
Traceback (most recent call last):
  File "/root/synapse/env/lib/python3.6/site-packages/synapse/http/server.py", line 81, in wrapped_request_handler
    yield h(self, request)
  File "/root/synapse/env/lib/python3.6/site-packages/synapse/http/server.py", line 316, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/root/synapse/env/lib/python3.6/site-packages/synapse/rest/client/v1/login.py", line 149, in on_POST
    result = yield self._do_other_login(login_submission)
  File "/root/synapse/env/lib/python3.6/site-packages/synapse/rest/client/v1/login.py", line 246, in _do_other_login
    login_submission,
  File "/root/synapse/env/lib/python3.6/site-packages/synapse/handlers/auth.py", line 679, in validate_login
    qualified_user_id, password,
  File "/root/synapse/env/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/root/synapse/env/lib/python3.6/site-packages/rest_auth_provider.py", line 51, in check_password
    if not r["auth"]:
TypeError: list indices must be integers or slices, not str

The response body of the Matrix API is as follows: "{"errcode":"M_UNKNOWN","error":"Internal server error"}"

LDAP/AD name displayname problem

I've followed https://github.com/kamax-matrix/mxisd/blob/master/docs/stores/ldap.md

in mxisd.yaml I have:

ldap:
  enabled: true
  connection:
    host: 'xxx'
    port: 389
    bindDn: 'CN=xxx,OU=xxx,DC=xxx,DC=xxx'
    bindPassword: 'xxx'
    baseDNs:
      - 'OU=xxx,DC=xxx,DC=xxx'
  attribute:
    name: 'cn'

and in homserver.yaml

password_providers:
  - module: "rest_auth_provider.RestAuthProvider"
    config:
      endpoint: "http://localhost:8090"
      policy:
        registration:
          profile:
            name: true
        login:
          profile:
            name: true

When loggin in with riot-web I can see the name correctly changing on every login in the left corner whether I set the name: attribute in myisd.yaml to either 'cn':

riot_cn

or 'displayName':

riot_displayname

so generally it appear to work so far.

However my question is in the riot-web/matrix profile the "Display Name" is not applied and/or changing accordingly, so in the rooms I'm still appearing with the matrixid:server.xxx instead of the correct name: transferred by mxisd via LDAP:

riot_web

Is there anything I'm missing out?

AttributeError: 'Handlers' object has no attribute 'profile_handler'

I'm trying to get the synapse Homeserver to work with a LDAP directory as authentication provider and mxisd seems to be appropriate for that. According to the manual this REST authentication provider is needed to make this work. Although the LDAP query seems to work, I get this exception in the synapse log:

2017-10-29 20:26:46,264 - rest_auth_provider - 46 - INFO - POST-0- Got password check for @mmueller:localhost
2017-10-29 20:26:46,296 - rest_auth_provider - 62 - INFO - POST-0- User @mmueller:localhost authenticated
2017-10-29 20:26:46,299 - rest_auth_provider - 76 - INFO - POST-0- User @mmueller:localhost already exists, registration skipped
2017-10-29 20:26:46,300 - rest_auth_provider - 79 - INFO - POST-0- Handling profile data
2017-10-29 20:26:46,301 - synapse.http.server - 139 - ERROR - POST-0- Failed handle request synapse.http.server._async_render on <synapse.rest.ClientRestResource object at 0x7fd4074ce1d0>: <XForwardedForRequest at 0x7fd406f531b8 method=POST uri=/_matrix/client/r0/login? clientproto=HTTP/1.1 site=8008>
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/synapse/http/server.py", line 116, in wrapped_request_handler
    yield request_handler(self, request, request_metrics)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/local/lib/python2.7/dist-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/local/lib/python2.7/dist-packages/synapse/http/server.py", line 257, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/local/lib/python2.7/dist-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/local/lib/python2.7/dist-packages/synapse/rest/client/v1/login.py", line 140, in on_POST
    result = yield self.do_password_login(login_submission)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/local/lib/python2.7/dist-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/local/lib/python2.7/dist-packages/synapse/rest/client/v1/login.py", line 221, in do_password_login
    password=login_submission["password"],
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/local/lib/python2.7/dist-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/local/lib/python2.7/dist-packages/synapse/handlers/auth.py", line 519, in _check_password
    is_valid = yield provider.check_password(user_id, password)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
    result = g.send(result)
  File "/usr/lib/python2.7/dist-packages/rest_auth_provider.py", line 82, in check_password
    store = yield self.account_handler.hs.get_handlers().profile_handler.store
AttributeError: 'Handlers' object has no attribute 'profile_handler'

Judging from the traceback, this issue seems to be caused by line 82 in rest_auth_provider.py

I was able to fix this issue by replacing that line with the following code:

            store = yield self.account_handler.hs.get_datastore()

Short guide for nextcloud integration?

This seems really interesting. As you already mention Nextcloud in the readme, is there somewhere a more detailed guide how this could be made to work?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.