Exemplo 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!"
Exemplo n.º 2
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!"
Exemplo n.º 3
0
class BaseController(WSGIController):

    def __call__(self, environ, start_response):
        """Invoke the Controller"""
        # WSGIController.__call__ dispatches to the Controller method
        # the request is routed to. This routing information is
        # available in environ['pylons.routes_dict']

        return WSGIController.__call__(self, environ, start_response)


    def __init__(self, *args, **kw):

        self.context = {}

        self.conn = None
        self.request = request
        self.response = response
        self.set_language(request.headers)

        self.parent = super(WSGIController, self)
        self.parent.__init__(*args, **kw)

        self.config = app_config['app_conf']
        self.here = app_config['here']
        self.browser_language = request.headers.get('Accept-Language', None)

        try:
            self.base_url = self.config['linotp_url']
            #trim trailing slashes
            while self.base_url[-1] == '/':
                self.base_url = self.base_url[:-1]
        except KeyError:
            raise Exception("Missing definition of remote linotp url"
                            " in application ini: linotp_url")

        # load keyfile
        client_key = self.config.get('client_key', None)
        self.client_key = None
        # replace the app root %here% if any
        if client_key and '%(here)s' in client_key:
            client_key = client_key.replace('%(here)s', self.here)

        if client_key:
            if os.path.exists(client_key):
                self.client_key = client_key
            else:
                log.error("key_file %s could not be found", client_key)

        # load the client certificate file
        client_cert = self.config.get('client_cert', None)
        self.client_cert = None
        # replace the app root %here% if any
        if client_cert and '%(here)s' in client_cert:
            client_cert = client_cert.replace('%(here)s', self.here)

        if client_cert:
            if os.path.exists(client_cert):
                self.client_cert = client_cert
            else:
                log.error("cert_file %s could not be found", client_cert)

        # load the server certificate file
        server_cert = self.config.get('server_cert', None)
        self.server_cert = None
        # replace the app root %here% if any
        if server_cert and '%(here)s' in server_cert:
            server_cert = server_cert.replace('%(here)s', self.here)

        if server_cert:
            if os.path.exists(server_cert):
                self.server_cert = server_cert
            else:
                log.error("cert_file %s could not be found", server_cert)

        self.remote_base = self.config.get('linotp_remote_base', '/userservice')

        return

    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)

            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()


    def get_preauth_context(self, params=None):
        """
        get required context information before the user is authenticated
        """
        if params is None:
            params = {}

        context = self.call_linotp('/userservice/pre_context', params=params)
        return context


    def get_context(self, params=None):
        """
        retrieve the selfservice defintion in the scope of the
        authenticated user
        """
        if params is None:
            params = {}
        context = self.call_linotp('/userservice/context', params=params)
        return context


    def set_language(self, headers):
        '''Invoke before everything else. And set the translation language'''
        languages = headers.get('Accept-Language', '').split(';')

        found_lang = False

        for language in languages:
            for lang in language.split(','):
                try:
                    if lang[:2] == "en":
                        found_lang = True
                        break
                    if lang == 'de':
                        pass
                    set_lang(lang)
                    found_lang = True
                    break
                except LanguageError as exx:
                    pass

            if found_lang is True:
                break

        if found_lang is False:
            log.warning("Cannot set preferred language: %r" % languages)

        return

    def sendError(self, response, exception, errId=311, context=None):
        """
        return an error response to the client
        """
        version = get_version()
        id = '1.0'

        ## handle the different types of exception:
        ## Exception, LinOtpError, str/unicode
        if (hasattr(exception, '__class__') == True
            and isinstance(exception, Exception)):
                errDesc = unicode(exception)
        elif type(exception) in [str, unicode]:
            errDesc = unicode(exception)
        else:
            errDesc = u"%r" % exception

        response.content_type = 'application/json'
        res = { "jsonrpc": "2.0",
                "result" :
                    {"status": False,
                        "error": {
                            "code"    :   errId,
                            "message" :   errDesc,
                            },
                    },
                 "version": version,
                 "id": id
            }

        ret = json.dumps(res, indent=3)

        if context in ['before', 'after']:
            response._exception = exception
            response.body = ret
            ret = response

        return res
Exemplo n.º 4
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)

            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()
Exemplo n.º 5
0
class LinOTPUserAuthPlugin(object):

    implements(IAuthenticator)

    def __init__(self, linotp_url, client_cert=None, client_key=None,
                 server_cert=None):
        self.conn = None

        self.base_url = linotp_url.strip('/')

        # load keyfile
        self.client_key = None
        # replace the app root %here% if any
        if client_key and '%(here)s' in client_key:
            client_key = client_key.replace('%(here)s', self.here)

        if client_key:
            if os.path.exists(client_key):
                self.client_key = client_key
            else:
                log.error("key_file %s could not be found", client_key)

        # load the client certificate file
        self.client_cert = None
        # replace the app root %here% if any
        if client_cert and '%(here)s' in client_cert:
            client_cert = client_cert.replace('%(here)s', self.here)

        if client_cert:
            if os.path.exists(client_cert):
                self.client_cert = client_cert
            else:
                log.error("cert_file %s could not be found", client_cert)

        # load the server certificate file
        self.server_cert = None
        # replace the app root %here% if any
        if server_cert and '%(here)s' in server_cert:
            server_cert = server_cert.replace('%(here)s', self.here)

        if server_cert:
            if os.path.exists(server_cert):
                self.server_cert = server_cert
            else:
                log.error("cert_file %s could not be found", server_cert)


    # IAuthenticatorPlugin
    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!"

    def __repr__(self):
        return '<%s %s>' % (self.__class__.__name__,
                            id(self))
Exemplo n.º 6
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!"
Exemplo n.º 7
0
class LinOTPUserAuthPlugin(object):

    implements(IAuthenticator)

    def __init__(self,
                 linotp_url,
                 client_cert=None,
                 client_key=None,
                 server_cert=None):
        self.conn = None

        self.base_url = linotp_url.strip('/')

        # load keyfile
        self.client_key = None
        # replace the app root %here% if any
        if client_key and '%(here)s' in client_key:
            client_key = client_key.replace('%(here)s', self.here)

        if client_key:
            if os.path.exists(client_key):
                self.client_key = client_key
            else:
                log.error("key_file %s could not be found", client_key)

        # load the client certificate file
        self.client_cert = None
        # replace the app root %here% if any
        if client_cert and '%(here)s' in client_cert:
            client_cert = client_cert.replace('%(here)s', self.here)

        if client_cert:
            if os.path.exists(client_cert):
                self.client_cert = client_cert
            else:
                log.error("cert_file %s could not be found", client_cert)

        # load the server certificate file
        self.server_cert = None
        # replace the app root %here% if any
        if server_cert and '%(here)s' in server_cert:
            server_cert = server_cert.replace('%(here)s', self.here)

        if server_cert:
            if os.path.exists(server_cert):
                self.server_cert = server_cert
            else:
                log.error("cert_file %s could not be found", server_cert)

    # IAuthenticatorPlugin
    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!"

    def __repr__(self):
        return '<%s %s>' % (self.__class__.__name__, id(self))
Exemplo n.º 8
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!"
Exemplo n.º 9
0
class BaseController(WSGIController):
    def __call__(self, environ, start_response):
        """Invoke the Controller"""
        # WSGIController.__call__ dispatches to the Controller method
        # the request is routed to. This routing information is
        # available in environ['pylons.routes_dict']

        return WSGIController.__call__(self, environ, start_response)

    def __init__(self, *args, **kw):

        self.context = {}

        self.conn = None
        self.request = request
        self.response = response
        self.set_language(request.headers)

        self.parent = super(WSGIController, self)
        self.parent.__init__(*args, **kw)

        self.config = app_config['app_conf']
        self.here = app_config['here']
        self.browser_language = request.headers.get('Accept-Language', None)

        try:
            self.base_url = self.config['linotp_url']
            #trim trailing slashes
            while self.base_url[-1] == '/':
                self.base_url = self.base_url[:-1]
        except KeyError:
            raise Exception("Missing definition of remote linotp url"
                            " in application ini: linotp_url")

        # load keyfile
        client_key = self.config.get('client_key', None)
        self.client_key = None
        # replace the app root %here% if any
        if client_key and '%(here)s' in client_key:
            client_key = client_key.replace('%(here)s', self.here)

        if client_key:
            if os.path.exists(client_key):
                self.client_key = client_key
            else:
                log.error("key_file %s could not be found", client_key)

        # load the client certificate file
        client_cert = self.config.get('client_cert', None)
        self.client_cert = None
        # replace the app root %here% if any
        if client_cert and '%(here)s' in client_cert:
            client_cert = client_cert.replace('%(here)s', self.here)

        if client_cert:
            if os.path.exists(client_cert):
                self.client_cert = client_cert
            else:
                log.error("cert_file %s could not be found", client_cert)

        # load the server certificate file
        server_cert = self.config.get('server_cert', None)
        self.server_cert = None
        # replace the app root %here% if any
        if server_cert and '%(here)s' in server_cert:
            server_cert = server_cert.replace('%(here)s', self.here)

        if server_cert:
            if os.path.exists(server_cert):
                self.server_cert = server_cert
            else:
                log.error("cert_file %s could not be found", server_cert)

        self.remote_base = self.config.get('linotp_remote_base',
                                           '/userservice')

        return

    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()

    def get_preauth_context(self, params=None):
        """
        get required context information before the user is authenticated
        """
        if params is None:
            params = {}

        context = self.call_linotp('/userservice/pre_context', params=params)
        return context

    def get_context(self, params=None):
        """
        retrieve the selfservice defintion in the scope of the
        authenticated user
        """
        if params is None:
            params = {}
        context = self.call_linotp('/userservice/context', params=params)
        return context

    def set_language(self, headers):
        '''Invoke before everything else. And set the translation language'''
        languages = headers.get('Accept-Language', '')

        found_lang = False

        for match in accept_language_regexp.finditer(languages):
            # make sure we have a correct language code format
            language = match.group(1)
            if not language:
                continue
            language = language.replace('_', '-').lower()

            # en is the default language
            if language.split('-')[0] == 'en':
                found_lang = True
                break

            try:
                set_lang(language.split('-')[0])
                found_lang = True
                break
            except LanguageError:
                log.debug(
                    "Cannot set requested language: %s. Trying next language if available.",
                    language)

        if not found_lang:
            log.warning("Cannot set preferred language: %r" % languages)

        return

    def sendError(self, response, exception, errId=311, context=None):
        """
        return an error response to the client
        """
        version = get_version()
        id = '1.0'

        ## handle the different types of exception:
        ## Exception, LinOtpError, str/unicode
        if (hasattr(exception, '__class__') == True
                and isinstance(exception, Exception)):
            errDesc = unicode(exception)
        elif type(exception) in [str, unicode]:
            errDesc = unicode(exception)
        else:
            errDesc = u"%r" % exception

        response.content_type = 'application/json'
        res = {
            "jsonrpc": "2.0",
            "result": {
                "status": False,
                "error": {
                    "code": errId,
                    "message": errDesc,
                },
            },
            "version": version,
            "id": id
        }

        ret = json.dumps(res, indent=3)

        if context in ['before', 'after']:
            response._exception = exception
            response.body = ret
            ret = response

        return res
Exemplo n.º 10
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()