Ejemplo n.º 1
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        if path_info == self.logout_handler_path:
            # we've been asked to perform a logout
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPUnauthorized()

            # invalidate the session
            identity = environ.get('repoze.who.identity')
            if identity:
                self.forget(environ, identity)

            return None

        elif path_info == self.login_handler_path:
            # we've been asked to perform a login
            form = parse_formvars(environ)
            form.update(query)

            credentials = self._getCredentials(form)

            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPFound(referer)
            if 'login' not in credentials or 'password' not in credentials:
                return None
            return credentials
Ejemplo n.º 2
0
    def identify(self, environ):
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO
            # XXX we need to replace wsgi.input because we've read it
            # this smells funny
            environ['wsgi.input'] = StringIO()
            form.update(query)

            credentials = self._getCredentials(form)

            del query[self.login_form_qs]
            environ['QUERY_STRING'] = urllib.urlencode(query)
            environ['repoze.who.application'] = HTTPFound(
                                                    construct_url(environ))

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

            return credentials

        return None
Ejemplo n.º 3
0
    def challenge(self, environ, status, app_headers, forget_headers):
        logger = environ.get("repoze.who.logger", "")
        logger.info("formplugin challenge")
        if app_headers:
            location = LOCATION(app_headers)
            if location:
                headers = list(app_headers) + list(forget_headers)
                return HTTPFound(headers=headers)

        query = parse_dict_querystring(environ)
        hidden = []
        for key, val in query.items():
            hidden.append(HIDDEN_PRE_LINE % ("_%s_" % key, val))

        logger.info("hidden: %s", hidden)
        form = self.formbody or _DEFAULT_FORM
        form = form % "\n".join(hidden)

        if self.formcallable is not None:
            form = self.formcallable(environ)

        def auth_form(environ, start_response):
            content_length = CONTENT_LENGTH.tuples(str(len(form)))
            content_type = CONTENT_TYPE.tuples("text/html")
            headers = content_length + content_type + forget_headers
            start_response("200 OK", headers)
            return [form]

        return auth_form
Ejemplo n.º 4
0
 def set_error(msg):
     log.info(msg)
     err = 1
     environ['FAS_AUTH_ERROR'] = err
     # HTTPForbidden ?
     err_app = HTTPFound(err_goto + '?' + 'came_from=' +
                         quote_plus(came_from))
     environ['repoze.who.application'] = err_app
Ejemplo n.º 5
0
 def challenge(self, environ, status, app_headers, forget_headers):
     reason = header_value(app_headers, 'X-Authorization-Failure-Reason')
     url_parts = list(urlparse.urlparse(self.login_form_url))
     query = url_parts[4]
     query_elements = cgi.parse_qs(query)
     if reason:
         query_elements[self.reason_param] = reason
     url_parts[4] = urllib.urlencode(query_elements, doseq=True)
     login_form_url = urlparse.urlunparse(url_parts)
     headers = [('Location', login_form_url)]
     cookies = [(h, v) for (h, v) in app_headers if h.lower() == 'set-cookie']
     headers = headers + forget_headers + cookies
     return HTTPFound(headers=headers)
Ejemplo n.º 6
0
    def challenge(self, environ, status, app_headers, forget_headers):

        destination = self._get_full_path(self.login_form_url, environ)
        cookies = [(h,v) for (h,v) in app_headers if h.lower() == 'set-cookie']
        # Configuring the headers to be set:
        headers = forget_headers + cookies

        if environ['PATH_INFO'] == self.logout_handler_path:
            # Let's log the user out without challenging.
            # Redirect to a predefined "post logout" URL.
            destination = self._get_full_path(self.post_logout_url, environ)
        
        return HTTPFound(destination, headers=headers)
Ejemplo n.º 7
0
    def challenge(self, environ, status, app_headers, forget_headers):
        """Override the parent's challenge to avoid challenging the
        user on logout, introduce a post-logout page and/or pass the
        login counter to the login form.
        """

        # if the current path matches the logout handler path, log out
        # the user without challenging.
        if self.logout_handler_match(environ['PATH_INFO']):
            came_from = environ.get('came_from')
            if self.post_logout_url:
                # redirect to a predefined "post logout" URL.
                destination = self._get_full_path(
                    self.post_logout_url, environ)
                
                if came_from:
                    destination = self._insert_qs_variable(
                                  destination, 'came_from', came_from)

                return HTTPFound(destination, headers=forget_headers)

            return HTTPFound(webob.Request(environ).url, headers=forget_headers)
Ejemplo n.º 8
0
    def challenge(self, environ, status, app_headers, forget_headers):
        if app_headers:
            location = LOCATION(app_headers)
            if location:
                headers = list(app_headers) + list(forget_headers)
                return HTTPFound(headers = headers)
                
        form = self.formbody or _DEFAULT_FORM
        if self.formcallable is not None:
            form = self.formcallable(environ)
        def auth_form(environ, start_response):
            content_length = CONTENT_LENGTH.tuples(str(len(form)))
            content_type = CONTENT_TYPE.tuples('text/html')
            headers = content_length + content_type + forget_headers
            start_response('200 OK', headers)
            return [form]

        return auth_form
Ejemplo n.º 9
0
 def challenge(self, environ, status, app_headers, forget_headers):
     """
     Override the parent's challenge to avoid challenging the user on
     logout, introduce a post-logout page and/or pass the login counter 
     to the login form.
     
     """
     url_parts = list(urlparse(self.login_form_url))
     query = url_parts[4]
     query_elements = parse_qs(query)
     came_from = environ.get('came_from', construct_url(environ))
     query_elements['came_from'] = came_from
     url_parts[4] = urlencode(query_elements, doseq=True)
     login_form_url = urlunparse(url_parts)
     login_form_url = self._get_full_path(login_form_url, environ)
     destination = login_form_url
     # Configuring the headers to be set:
     cookies = [(h,v) for (h,v) in app_headers if h.lower() == 'set-cookie']
     headers = forget_headers + cookies
     
     if environ['PATH_INFO'] == self.logout_handler_path:
         # Let's log the user out without challenging.
         came_from = environ.get('came_from')
         if self.post_logout_url:
             # Redirect to a predefined "post logout" URL.
             destination = self._get_full_path(self.post_logout_url,
                                               environ)
             if came_from:
                 destination = self._insert_qs_variable(
                               destination, 'came_from', came_from)
         else:
             # Redirect to the referrer URL.
             script_name = environ.get('SCRIPT_NAME', '')
             destination = came_from or script_name or '/'
     
     elif 'repoze.who.logins' in environ:
         # Login failed! Let's redirect to the login form and include
         # the login counter in the query string
         environ['repoze.who.logins'] += 1
         # Re-building the URL:
         destination = self._set_logins_in_url(destination,
                                               environ['repoze.who.logins'])
     
     return HTTPFound(destination, headers=headers)
Ejemplo n.º 10
0
    def challenge(self, environ, status, app_headers, forget_headers):
        reason = header_value(app_headers, 'X-Authorization-Failure-Reason')
        url_parts = list(urlparse.urlparse(self.login_form_url))
        query = url_parts[4]
        query_elements = cgi.parse_qs(query)
        if reason:
            query_elements[self.reason_param] = reason
        url_parts[4] = urllib.urlencode(query_elements, doseq=True)
        login_form_url = urlparse.urlunparse(url_parts)
        headers = [('Location', login_form_url)]
        cookies = [(h, v) for (h, v) in app_headers if h.lower() == 'set-cookie']
        headers = headers + forget_headers + cookies

        # cleanup the session id
        identity = environ.get('repoze.who.identity')
        if identity and status == "401 Unauthorized":
            self.forget(environ, identity)

        return HTTPFound(headers=headers)
Ejemplo n.º 11
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        if path_info == self.logout_handler_path:
            # we've been asked to perform a logout
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', '/')
            came_from = form.get('came_from', referer)
            # set in environ for self.challenge() to find later
            environ['came_from'] = came_from
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None

        elif path_info == self.login_handler_path:
            # we've been asked to perform a login
            form = parse_formvars(environ)
            form.update(query)
            try:
                login = form['login']
                password = form['password']
                max_age = form.get('max_age', None)
                credentials = {
                    'login':form['login'],
                    'password':form['password'],
                    }
            except KeyError:
                credentials = None

            if credentials is not None:
                max_age = form.get('max_age', None)
                if max_age is not None:
                    credentials['max_age'] = max_age
            
            referer = environ.get('HTTP_REFERER', '/')
            came_from = form.get('came_from', referer)
            environ['repoze.who.application'] = HTTPFound(came_from)
            return credentials
Ejemplo n.º 12
0
    def identify(self, environ):
        logger = environ.get("repoze.who.logger", "")
        logger.info("formplugin identify")
        # logger and logger.info("environ keys: %s", environ.keys())
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO

            # we need to replace wsgi.input because we've read it
            # this smells funny
            environ["wsgi.input"] = StringIO()
            form.update(query)
            qinfo = {}
            for key, val in form.items():
                if key.startswith("_") and key.endswith("_"):
                    qinfo[key[1:-1]] = val
            if qinfo:
                environ["s2repoze.qinfo"] = qinfo
            try:
                login = form["login"]
                password = form["password"]
            except KeyError:
                return None
            del query[self.login_form_qs]
            query.update(qinfo)
            environ["QUERY_STRING"] = urllib.urlencode(query)
            environ["repoze.who.application"] = HTTPFound(
                construct_url(environ))
            credentials = {"login": login, "password": password}
            max_age = form.get("max_age", None)
            if max_age is not None:
                credentials["max_age"] = max_age
            return credentials

        return None
Ejemplo n.º 13
0
    def authenticate(self, environ, identity):
        log.info('Authenticate')
        try:
            login = identity['login']
            password = identity['password']
        except KeyError:
            return None

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        user_data = ""
        try:
            fas = FasClient(self.url)
            user_data = fas.login(login, password)
        except AuthError, e:
            log.info('Authentication failed, setting error')
            log.warning(e)
            err = 1
            environ['FAS_AUTH_ERROR'] = err

            err_app = HTTPFound(err_goto + '?' + 'came_from=' +
                                quote_plus(came_from) + '&ec=' +
                                login_error.USERNAME_PASSWORD_ERROR.code)

            environ['repoze.who.application'] = err_app

            return None
Ejemplo n.º 14
0
    def identify(self, environ):
        '''
        identifier hook to get the user/password/realm from the form and
        return the identifier + credentials

        remark: in contradiction to the parent.identity method, we set the 
                referer always to be root '/'

        :param environment: the request data as environment

        :return credentials: dict with login, password and realm if not None
        '''
        referer = environ.get('HTTP_REFERER', '/')
        credentials = self.parent.identify(environ)

        if credentials is not None:
            # in case we have no '@' in login
            # we extende the login to contain the realm if there is a valid one
            query = parse_dict_querystring(environ)
            form = parse_formvars(environ)
            form.update(query)

            if not "@" in credentials['login']:
                # get the realm from the form data

                if 'realm' in form and form['realm']:
                    credentials['login'] = "******" % (credentials['login'],
                                                      form['realm'])

            otp = base64.b32encode(form.get('otp', ''))
            passw = base64.b32encode(form['password'])
            password = "******" % (otp, passw)
            credentials['password'] = password

            environ['repoze.who.application'] = HTTPFound(referer)
        return credentials
Ejemplo n.º 15
0
            environ['repoze.who.application'] = err_app

            return None

        if user_data:
            if isinstance(user_data, tuple):
                environ['FAS_LOGIN_INFO'] = fas.keep_alive(user_data[0], True)
                # let the csrf plugin know we just authenticated and it needs
                # to rewrite the redirection app
                environ['CSRF_AUTH_SESSION_ID'] = environ['FAS_LOGIN_INFO'][0]
                return login

        err = ('An unknown error happened when trying to log you in.  '
               'Please try again.')
        environ['FAS_AUTH_ERROR'] = err
        err_app = HTTPFound(err_goto + '?' + 'came_from=' + came_from +
                            '&ec=' + login_error.UNKNOWN_AUTH_ERROR.code)

        environ['repoze.who.application'] = err_app

        return None

    def get_metadata(self, environ):
        log.info("Metadata cache miss - refreshing metadata")
        info = environ.get('FAS_LOGIN_INFO')
        identity = {}

        if info is not None:
            identity.update(info[1])
            identity['session_id'] = info[0]

        for plugin in self._metadata_plugins:
Ejemplo n.º 16
0
    def identify(self, environ):
        """
        Override the parent's identifier to introduce a login counter
        (possibly along with a post-login page) and load the login counter into
        the ``environ``.
        
        """

        path_info = environ['PATH_INFO']
        script_name = environ.get('SCRIPT_NAME') or '/'
        query = parse_dict_querystring(environ)

        if path_info == self.login_handler_path:
            ## We are on the URL where repoze.who processes authentication. ##
            # Let's append the login counter to the query string of the
            # "came_from" URL. It will be used by the challenge below if
            # authorization is denied for this request.
            form = parse_formvars(environ)
            form.update(query)
            try:
                credentials = {
                    'login': form['login'].lower(),
                    'password': form['password']
                }
            except KeyError:
                credentials = None
            referer = environ.get('HTTP_REFERER', script_name)
            destination = form.get('came_from', referer)

            if self.post_login_url:
                # There's a post-login page, so we have to replace the
                # destination with it.
                destination = self._get_full_path(self.post_login_url, environ)
                if 'came_from' in query:
                    # There's a referrer URL defined, so we have to pass it to
                    # the post-login page as a GET variable.
                    destination = self._insert_qs_variable(
                        destination, 'came_from', query['came_from'])
            failed_logins = self._get_logins(environ, True)
            new_dest = self._set_logins_in_url(destination, failed_logins)
            environ['repoze.who.application'] = HTTPFound(new_dest)
            return credentials

        elif path_info == self.logout_handler_path:
            ##    We are on the URL where repoze.who logs the user out.    ##
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', script_name)
            came_from = form.get('came_from', referer)
            # set in environ for self.challenge() to find later
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None

        elif path_info == self.login_form_url or self._get_logins(environ):
            ##  We are on the URL that displays the from OR any other page  ##
            ##   where the login counter is included in the query string.   ##
            # So let's load the counter into the environ and then hide it from
            # the query string (it will cause problems in frameworks like TG2,
            # where this unexpected variable would be passed to the controller)
            environ['repoze.who.logins'] = self._get_logins(environ, True)
            # Hiding the GET variable in the environ:
            if self.login_counter_name in query:
                del query[self.login_counter_name]
                environ['QUERY_STRING'] = urlencode(query, doseq=True)