Regstration with email in v2

This commit is contained in:
David Baker 2015-04-15 15:50:38 +01:00
parent 4eb6d66b45
commit a19b739909
6 changed files with 123 additions and 29 deletions

View file

@ -30,6 +30,7 @@ from .admin import AdminHandler
from .appservice import ApplicationServicesHandler
from .sync import SyncHandler
from .auth import AuthHandler
from .identity import IdentityHandler
class Handlers(object):
@ -60,3 +61,4 @@ class Handlers(object):
)
self.sync_handler = SyncHandler(hs)
self.auth_handler = AuthHandler(hs)
self.identity_handler = IdentityHandler(hs)

View file

@ -20,6 +20,7 @@ from synapse.api.constants import LoginType
from synapse.types import UserID
from synapse.api.errors import LoginError, Codes
from synapse.http.client import SimpleHttpClient
from synapse.util.async import run_on_reactor
from twisted.web.client import PartialDownloadError
@ -40,6 +41,7 @@ class AuthHandler(BaseHandler):
self.checkers = {
LoginType.PASSWORD: self._check_password_auth,
LoginType.RECAPTCHA: self._check_recaptcha,
LoginType.EMAIL_IDENTITY: self._check_email_identity,
}
self.sessions = {}
@ -54,24 +56,37 @@ class AuthHandler(BaseHandler):
authdict: The dictionary from the client root level, not the
'auth' key: this method prompts for auth if none is sent.
Returns:
A tuple of authed, dict where authed is true if the client
has successfully completed an auth flow. If it is true, the dict
contains the authenticated credentials of each stage.
If authed is false, the dictionary is the server response to the
login request and should be passed back to the client.
A tuple of authed, dict, dict where authed is true if the client
has successfully completed an auth flow. If it is true, the first
dict contains the authenticated credentials of each stage.
If authed is false, the first dictionary is the server response to
the login request and should be passed back to the client.
In either case, the second dict contains the parameters for this
request (which may have been given only in a previous call).
"""
if not clientdict or 'auth' not in clientdict:
sess = self._get_session_info(None)
authdict = None
sid = None
if clientdict and 'auth' in clientdict:
authdict = clientdict['auth']
del clientdict['auth']
if 'session' in authdict:
sid = authdict['session']
sess = self._get_session_info(sid)
if len(clientdict) > 0:
sess['clientdict'] = clientdict
self._save_session(sess)
elif 'clientdict' in sess:
clientdict = sess['clientdict']
if not authdict:
defer.returnValue(
(False, self._auth_dict_for_flows(flows, sess))
(False, self._auth_dict_for_flows(flows, sess), clientdict)
)
authdict = clientdict['auth']
sess = self._get_session_info(
authdict['session'] if 'session' in authdict else None
)
if 'creds' not in sess:
sess['creds'] = {}
creds = sess['creds']
@ -89,11 +104,11 @@ class AuthHandler(BaseHandler):
if len(set(f) - set(creds.keys())) == 0:
logger.info("Auth completed with creds: %r", creds)
self._remove_session(sess)
defer.returnValue((True, creds))
defer.returnValue((True, creds, clientdict))
ret = self._auth_dict_for_flows(flows, sess)
ret['completed'] = creds.keys()
defer.returnValue((False, ret))
defer.returnValue((False, ret, clientdict))
@defer.inlineCallbacks
def add_oob_auth(self, stagetype, authdict, clientip):
@ -175,18 +190,25 @@ class AuthHandler(BaseHandler):
defer.returnValue(True)
raise LoginError(401, "", errcode=Codes.UNAUTHORIZED)
@defer.inlineCallbacks
def _check_email_identity(self, authdict, _):
yield run_on_reactor()
threepidCreds = authdict['threepidCreds']
identity_handler = self.hs.get_handlers().identity_handler
logger.debug("Getting validated threepid. threepidcreds: %r" % (threepidCreds,))
threepid = yield identity_handler.threepid_from_creds(threepidCreds)
defer.returnValue(threepid)
def _get_params_recaptcha(self):
return {"public_key": self.hs.config.recaptcha_public_key}
def _auth_dict_for_flows(self, flows, session):
public_flows = []
for f in flows:
hidden = False
for stagetype in f:
if stagetype in LoginType.HIDDEN_TYPES:
hidden = True
if not hidden:
public_flows.append(f)
public_flows.append(f)
get_params = {
LoginType.RECAPTCHA: self._get_params_recaptcha,

View file

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# Copyright 2015 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utilities for interacting with Identity Servers"""
from twisted.internet import defer
from synapse.api.errors import (
CodeMessageException
)
from ._base import BaseHandler
from synapse.http.client import SimpleHttpClient
from synapse.util.async import run_on_reactor
import json
import logging
logger = logging.getLogger(__name__)
class IdentityHandler(BaseHandler):
def __init__(self, hs):
super(IdentityHandler, self).__init__(hs)
@defer.inlineCallbacks
def threepid_from_creds(self, creds):
yield run_on_reactor()
# TODO: get this from the homeserver rather than creating a new one for
# each request
http_client = SimpleHttpClient(self.hs)
# XXX: make this configurable!
#trustedIdServers = ['matrix.org', 'localhost:8090']
trustedIdServers = ['matrix.org']
if not creds['idServer'] in trustedIdServers:
logger.warn('%s is not a trusted ID server: rejecting 3pid ' +
'credentials', creds['idServer'])
defer.returnValue(None)
data = {}
try:
data = yield http_client.get_json(
"https://%s%s" % (
creds['idServer'],
"/_matrix/identity/api/v1/3pid/getValidated3pid"
),
{'sid': creds['sid'], 'clientSecret': creds['clientSecret']}
)
except CodeMessageException as e:
data = json.loads(e.msg)
if 'medium' in data:
defer.returnValue(data)
defer.returnValue(None)

View file

@ -180,7 +180,11 @@ class RegistrationHandler(BaseHandler):
@defer.inlineCallbacks
def register_email(self, threepidCreds):
"""Registers emails with an identity server."""
"""
Registers emails with an identity server.
Used only by c/s api v1
"""
for c in threepidCreds:
logger.info("validating theeepidcred sid %s on id server %s",