Ejemplo n.º 1
0
    def authenticate(self, environ, identity):
        """
        authenticated user to the identity. If a auth cookie is given
        it is appended to the indentiy.

        :param environ: The WSGI environment.
        :param identity: The repoze.who's identity dictionary.

        """

        if 'login' not in identity or 'password' not in identity:
            return None

        login = identity['login']
        password = identity['password']

        try:
            if not self.conn:
                self.conn = Connection(self.base_url,
                                       server_cert=self.server_cert,
                                       client_cert=self.client_cert,
                                       client_key=self.client_key)
            params = {'login': login, 'password': password}
            headers = {
                "Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/plain"
            }

            if environ.get('HTTP_ACCEPT_LANGUAGE', None):
                headers['Accept-Language'] = environ.get(
                    'HTTP_ACCEPT_LANGUAGE', None)

            path = "/userservice/auth"

            response = self.conn.post(path, params=params, headers=headers)
            if response.status_code != 200:
                return "::ERROR:: Connection response: %s (%s) %r" % (
                    response.reason, path, response.status_code)

            res = response.json()
            authUser = res.get('result', {}).get('value', False)
            if authUser != False:
                cookie = response.get_cookie('userauthcookie')
                if cookie:
                    return "%s;%s" % (login, cookie)
                else:
                    return login
            else:
                return "::ERROR:: Authentication attempt failed!"

        except Exception as exx:
            log.error("[authenticate] %r" % exx)
            return "::ERROR:: Connection failed!"
Ejemplo n.º 2
0
    def add_metadata(self, environ, identity):
        """
        Add metadata about the authenticated user to the identity.

        It modifies the C{identity} dictionary to add the metadata.

        :param environ: The WSGI environment.
        :param identity: The repoze.who's identity dictionary.
        """

        params = {}
        headers = {
            "Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain"
        }

        # this part is used implicit:
        # on logout, there is no login and thus just return a None
        path = environ.get('PATH_INFO', '/logout')
        if '/logout' in path:
            return None

        # due to the requirement to transfer info back from repoze
        # authentication, we have to deal with the ::ERROR:: user
        if (identity and "::ERROR::" in identity.get('repoze.who.user',
                                                     '::ERROR::')):
            return None

        try:
            if not self.conn:
                self.conn = Connection(self.base_url,
                                       server_cert=self.server_cert,
                                       client_cert=self.client_cert,
                                       client_key=self.client_key)

            if environ.get('HTTP_ACCEPT_LANGUAGE', None):
                headers['Accept-Language'] = environ.get(
                    'HTTP_ACCEPT_LANGUAGE', None)

            if not self.conn.is_user_session_set:
                # for the authetication we take the 'repoze.who.userid' as it
                # is the one which is returned from the authenticate call
                # extended by the realm and joined with the auth_cookie
                if ';' in identity['repoze.who.userid']:
                    user, session = identity['repoze.who.userid'].split(';', 1)
                    self.conn.set_user_session(session, user)
                else:
                    user = identity['repoze.who.userid']
                    self.conn.set_user_session(None, user)

            path = "/userservice/userinfo"
            response = self.conn.post(path, params=params, headers=headers)

            if response.status_code == 200:
                res = response.json()
                user_data = res.get('result', {}).get('value', [])
                if type(user_data) in [dict]:
                    identity.update(user_data)

                # implicit return of enriched identity
                return identity

        except Exception as exx:
            log.error("[add_metadata] %r" % exx)
            return "::ERROR:: Connection failed!"
Ejemplo n.º 3
0
    def call_linotp(self, url, params=None, return_json=True):
        """
        make a http request to the linotp server

        :param url: the path of the linotp resource
        :param params: dict with request parameters
        :param return_json: bool, response should already be a json loaded obj

        :return: return the response of the request as dict or as plain text

        """
        if not self.conn:
            self.conn = Connection(self.base_url,
                                   server_cert=self.server_cert,
                                   client_cert=self.client_cert,
                                   client_key=self.client_key)

        if params is None:
            params = {}

        headers = {
            "Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain",
        }

        # for locale support, we copy the incomming languege settings
        if self.browser_language:
            headers['Accept-Language'] = self.browser_language

        if not self.conn.is_user_session_set:
            # if we are requesting for a user, provide the user auth cookie
            if 'user' in params:
                if hasattr(self, 'auth_cookie') and self.auth_cookie:
                    self.conn.set_user_session(self.auth_cookie,
                                               params['user'])

        path = url

        if 'session' in params:
            # If a session is contained in params it is the local selfservice
            # session (between the browser and this server) not the session
            # between selfservice and LinOTP. Therefore we delete it. The
            # selfservice->LinOTP session has already been set with
            # 'self.conn.set_user_session'
            del params['session']

        net_response = self.conn.post(path, params=params, headers=headers)

        if net_response.status_code != 200:
            error = "%s%s: %s - %s" % (self.config.get(
                'linotp_url',
                ''), path, net_response.status_code, net_response.reason)
            log.error(error)
            if net_response.reason == "Logout from LinOTP selfservice":
                raise SessionExpiratioException(
                    error,
                    url=self.config.get('linotp_url', ''),
                    path=path,
                    status_code=net_response.status_code,
                    reason=net_response.reason)

            raise InvalidLinOTPResponse(error,
                                        url=self.config.get('linotp_url', ''),
                                        path=path,
                                        status_code=net_response.status_code,
                                        reason=net_response.reason)

        return net_response.json() if return_json else net_response.text()