synapse/handlers/auth.py
def check_auth(self, flows, clientdict, clientip):
        """
        Takes a dictionary sent by the client in the login / registration
        protocol and handles the User-Interactive Auth flow.

        As a side effect, this function fills in the 'creds' key on the user's
        session with a map, which maps each auth-type (str) to the relevant
        identity authenticated by that auth-type (mostly str, but for captcha, bool).

        If no auth flows have been completed successfully, raises an
        InteractiveAuthIncompleteError. To handle this, you can use
        synapse.rest.client.v2_alpha._base.interactive_auth_handler as a
        decorator.

        Args:
            flows (list): A list of login flows. Each flow is an ordered list of
                          strings representing auth-types. At least one full
                          flow must be completed in order for auth to be successful.

            clientdict: The dictionary from the client root level, not the
                        'auth' key: this method prompts for auth if none is sent.

            clientip (str): The IP address of the client.

        Returns:
            defer.Deferred[dict, dict, str]: a deferred tuple of
                (creds, params, session_id).

                'creds' contains the authenticated credentials of each stage.

                'params' contains the parameters for this request (which may
                have been given only in a previous call).

                'session_id' is the ID of this session, either passed in by the
                client or assigned by this call

        Raises:
            InteractiveAuthIncompleteError if the client has not yet completed
                all the stages in any of the permitted flows.
        """

        authdict = None
        sid = None
        if clientdict and 'auth' in clientdict:
            authdict = clientdict['auth']
            del clientdict['auth']
            if 'session' in authdict:
                sid = authdict['session']
        session = self._get_session_info(sid)

        if len(clientdict) > 0:
            # This was designed to allow the client to omit the parameters
            # and just supply the session in subsequent calls so it split
            # auth between devices by just sharing the session, (eg. so you
            # could continue registration from your phone having clicked the
            # email auth link on there). It's probably too open to abuse
            # because it lets unauthenticated clients store arbitrary objects
            # on a home server.
            # Revisit: Assumimg the REST APIs do sensible validation, the data
            # isn't arbintrary.
            session['clientdict'] = clientdict
            self._save_session(session)
        elif 'clientdict' in session:
            clientdict = session['clientdict']

        if not authdict:
            raise InteractiveAuthIncompleteError(
                self._auth_dict_for_flows(flows, session),
            )

        if 'creds' not in session:
            session['creds'] = {}
        creds = session['creds']

        # check auth type currently being presented
        errordict = {}
        if 'type' in authdict:
            login_type = authdict['type']
            try:
                result = yield self._check_auth_dict(authdict, clientip)
                if result:
                    creds[login_type] = result
                    self._save_session(session)
            except LoginError as e:
                if login_type == LoginType.EMAIL_IDENTITY:
                    # riot used to have a bug where it would request a new
                    # validation token (thus sending a new email) each time it
                    # got a 401 with a 'flows' field.
                    # (https://github.com/vector-im/vector-web/issues/2447).
                    #
                    # Grandfather in the old behaviour for now to avoid
                    # breaking old riot deployments.
                    raise

                # this step failed. Merge the error dict into the response
                # so that the client can have another go.
                errordict = e.error_dict()

        for f in flows:
            if len(set(f) - set(creds.keys())) == 0:
                # it's very useful to know what args are stored, but this can
                # include the password in the case of registering, so only log
                # the keys (confusingly, clientdict may contain a password
                # param, creds is just what the user authed as for UI auth
                # and is not sensitive).
                logger.info(
                    "Auth completed with creds: %r. Client dict has keys: %r",
                    creds, clientdict.keys()
                )
                defer.returnValue((creds, clientdict, session['id']))

        ret = self._auth_dict_for_flows(flows, session)
        ret['completed'] = creds.keys()
        ret.update(errordict)
        raise InteractiveAuthIncompleteError(
            ret,
        )

        Takes a dictionary sent by the client in the login / registration
        protocol and handles the User-Interactive Auth flow.

        As a side effect, this function fills in the 'creds' key on the user's
        session with a map, which maps each auth-type (str) to the relevant
        identity authenticated by that auth-type (mostly str, but for captcha, bool).

        If no auth flows have been completed successfully, raises an
        InteractiveAuthIncompleteError. To handle this, you can use
        synapse.rest.client.v2_alpha._base.interactive_auth_handler as a
        decorator.

        Args:
            flows (list): A list of login flows. Each flow is an ordered list of
                          strings representing auth-types. At least one full
                          flow must be completed in order for auth to be successful.

            clientdict: The dictionary from the client root level, not the
                        'auth' key: this method prompts for auth if none is sent.

            clientip (str): The IP address of the client.

        Returns:
            defer.Deferred[dict, dict, str]: a deferred tuple of
                (creds, params, session_id).

                'creds' contains the authenticated credentials of each stage.

                'params' contains the parameters for this request (which may
                have been given only in a previous call).

                'session_id' is the ID of this session, either passed in by the
                client or assigned by this call

        Raises:
            InteractiveAuthIncompleteError if the client has not yet completed
                all the stages in any of the permitted flows.
        
Takes a dictionary sent by the client in the login / registration
protocol and handles the User-Interactive Auth flow.

As a side effect, this function fills in the 'creds' key on the user's
session with a map, which maps each auth-type (str) to the relevant
identity authenticated by that auth-type (mostly str, but for captcha, bool).

If no auth flows have been completed successfully, raises an
InteractiveAuthIncompleteError. To handle this, you can use
synapse.rest.client.v2_alpha._base.interactive_auth_handler as a
decorator.

flows (list): A list of login flows. Each flow is an ordered list of
strings representing auth-types. At least one full
flow must be completed in order for auth to be successful.

The dictionary from the client root level, not the
'auth' key: this method prompts for auth if none is sent.

clientip (str): The IP address of the client.

defer.Deferred[dict, dict, str]: a deferred tuple of
(creds, params, session_id).

'creds' contains the authenticated credentials of each stage.

'params' contains the parameters for this request (which may
have been given only in a previous call).

'session_id' is the ID of this session, either passed in by the
client or assigned by this call

InteractiveAuthIncompleteError if the client has not yet completed
all the stages in any of the permitted flows.
Takes a dictionary sent by the client in the login / registration protocol and handles the User - Interactive Auth flow . As a side effect this function fills in the ' creds ' key on the user ' s session with a map which maps each auth - type ( str ) to the relevant identity authenticated by that auth - type ( mostly str but for captcha bool ) . If no auth flows have been completed successfully raises an InteractiveAuthIncompleteError . To handle this you can use synapse . rest . client . v2_alpha . _base . interactive_auth_handler as a decorator . flows ( list ) : A list of login flows . Each flow is an ordered list of strings representing auth - types . At least one full flow must be completed in order for auth to be successful . The dictionary from the client root level not the ' auth ' key : this method prompts for auth if none is sent . clientip ( str ) : The IP address of the client . defer . Deferred [ dict dict str ] : a deferred tuple of ( creds params session_id ) . ' creds ' contains the authenticated credentials of each stage . ' params ' contains the parameters for this request ( which may have been given only in a previous call ) . ' session_id ' is the ID of this session either passed in by the client or assigned by this call InteractiveAuthIncompleteError if the client has not yet completed all the stages in any of the permitted flows .
def check_auth(self, flows, clientdict, clientip):
        authdict = None
        sid = None
        if clientdict and 'auth' in clientdict:
            authdict = clientdict['auth']
            del clientdict['auth']
            if 'session' in authdict:
                sid = authdict['session']
        session = self._get_session_info(sid)
        if len(clientdict) > 0:
            session['clientdict'] = clientdict
            self._save_session(session)
        elif 'clientdict' in session:
            clientdict = session['clientdict']
        if not authdict:
            raise InteractiveAuthIncompleteError(
                self._auth_dict_for_flows(flows, session),
            )
        if 'creds' not in session:
            session['creds'] = {}
        creds = session['creds']
        errordict = {}
        if 'type' in authdict:
            login_type = authdict['type']
            try:
                result = yield self._check_auth_dict(authdict, clientip)
                if result:
                    creds[login_type] = result
                    self._save_session(session)
            except LoginError as e:
                if login_type == LoginType.EMAIL_IDENTITY:
                     Grandfather in the old behaviour for now to avoid
                     breaking old riot deployments.
                    raise
                 this step failed. Merge the error dict into the response
                 so that the client can have another go.
                errordict = e.error_dict()
        for f in flows:
            if len(set(f) - set(creds.keys())) == 0:
                 it's very useful to know what args are stored, but this can
                 include the password in the case of registering, so only log
                 the keys (confusingly, clientdict may contain a password
                 param, creds is just what the user authed as for UI auth
                 and is not sensitive).
                logger.info(
                    "Auth completed with creds: %r. Client dict has keys: %r",
                    creds, clientdict.keys()
                )
                defer.returnValue((creds, clientdict, session['id']))
        ret = self._auth_dict_for_flows(flows, session)
        ret['completed'] = creds.keys()
        ret.update(errordict)
        raise InteractiveAuthIncompleteError(
            ret,
        )
def check_auth ( self , flows , clientdict , clientip ) : authdict = None sid = None if clientdict and 'auth' in clientdict : authdict = clientdict [ 'auth' ] del clientdict [ 'auth' ] if 'session' in authdict : sid = authdict [ 'session' ] session = self . _get_session_info ( sid ) if len ( clientdict ) > 0 : session [ 'clientdict' ] = clientdict self . _save_session ( session ) elif 'clientdict' in session : clientdict = session [ 'clientdict' ] if not authdict : raise InteractiveAuthIncompleteError ( self . _auth_dict_for_flows ( flows , session ) , ) if 'creds' not in session : session [ 'creds' ] = { } creds = session [ 'creds' ] errordict = { } if 'type' in authdict : login_type = authdict [ 'type' ] try : result = yield self . _check_auth_dict ( authdict , clientip ) if result : creds [ login_type ] = result self . _save_session ( session ) except LoginError as e : if login_type == LoginType . EMAIL_IDENTITY : raise errordict = e . error_dict ( ) for f in flows : if len ( set ( f ) - set ( creds . keys ( ) ) ) == 0 : logger . info ( "Auth completed with creds: %r. Client dict has keys: %r" , creds , clientdict . keys ( ) ) defer . returnValue ( ( creds , clientdict , session [ 'id' ] ) ) ret = self . _auth_dict_for_flows ( flows , session ) ret [ 'completed' ] = creds . keys ( ) ret . update ( errordict ) raise InteractiveAuthIncompleteError ( ret , )
Takes a dictionary sent by the client in the login / registration
protocol and handles the User-Interactive Auth flow.
Takes a dictionary sent by the client in the login / registration protocol and handles the User - Interactive Auth flow .
"""
        Takes a dictionary sent by the client in the login / registration
        protocol and handles the User-Interactive Auth flow.

        As a side effect, this function fills in the 'creds' key on the user's
        session with a map, which maps each auth-type (str) to the relevant
        identity authenticated by that auth-type (mostly str, but for captcha, bool).

        If no auth flows have been completed successfully, raises an
        InteractiveAuthIncompleteError. To handle this, you can use
        synapse.rest.client.v2_alpha._base.interactive_auth_handler as a
        decorator.

        Args:
            flows (list): A list of login flows. Each flow is an ordered list of
                          strings representing auth-types. At least one full
                          flow must be completed in order for auth to be successful.

            clientdict: The dictionary from the client root level, not the
                        'auth' key: this method prompts for auth if none is sent.

            clientip (str): The IP address of the client.

        Returns:
            defer.Deferred[dict, dict, str]: a deferred tuple of
                (creds, params, session_id).

                'creds' contains the authenticated credentials of each stage.

                'params' contains the parameters for this request (which may
                have been given only in a previous call).

                'session_id' is the ID of this session, either passed in by the
                client or assigned by this call

        Raises:
            InteractiveAuthIncompleteError if the client has not yet completed
                all the stages in any of the permitted flows.
        """ # This was designed to allow the client to omit the parameters # and just supply the session in subsequent calls so it split # auth between devices by just sharing the session, (eg. so you # could continue registration from your phone having clicked the # email auth link on there). It's probably too open to abuse # because it lets unauthenticated clients store arbitrary objects # on a home server. # Revisit: Assumimg the REST APIs do sensible validation, the data # isn't arbintrary. # check auth type currently being presented # riot used to have a bug where it would request a new # validation token (thus sending a new email) each time it # got a 401 with a 'flows' field. # (https://github.com/vector-im/vector-web/issues/2447). # # Grandfather in the old behaviour for now to avoid # breaking old riot deployments. # this step failed. Merge the error dict into the response # so that the client can have another go. # it's very useful to know what args are stored, but this can # include the password in the case of registering, so only log # the keys (confusingly, clientdict may contain a password # param, creds is just what the user authed as for UI auth # and is not sensitive).
self
flows
clientdict
clientip