Exemple #1
0
    def post(self, request, assertion):
        """Logs a user in (establishes a session cookie).

        Verifies BrowserID assertion and check that a user with an
        email verified by the BrowserID is known (added to users
        list).
        """
        if assertion == None:
            return http.HttpResponseBadRequest('BrowserId assertion not set.')
        try:
            user = auth.authenticate(site=request.site,
                                     site_url=request.site_url,
                                     assertion=assertion)
        except AssertionVerificationException as ex:
            logger.debug('Assertion verification failed.')
            return http.HttpResponseBadRequest(str(ex))
        if user is not None:
            auth.login(request, user)

            # Store all user data needed by Auth view in session, this
            # way, user table does not need to be queried during the
            # performance critical request (sessions are cached).
            request.session['user_id'] = user.id
            logger.debug('%s successfully logged.' % (user.email))
            return http.HttpResponseNoContent()
        else:
            # Unkown user.
            # Return not authorized because request was well formed (400
            # doesn't seem appropriate).
            return http.HttpResponseNotAuthorized()
Exemple #2
0
    def get(self, request):
        """Logs a user in (establishes a session cookie).

        Verifies a token and check that a user with an email encoded
        in the token is known.

        On success redirects to path passed in the 'next' url
        argument.
        """
        # TODO(jw): should this first check if the user is already
        # logged in and redirect to '/' if this is the case?
        token = request.GET.get('token')
        if token == None:
            return http.HttpResponseBadRequest('Token missing.')
        try:
            user = auth.authenticate(site=request.site,
                                     site_url=request.site_url,
                                     token=token)
        except AuthenticationError as ex:
            logger.debug('Token verification failed.')
            return http.HttpResponseBadRequest(str(ex))
        if user is not None:
            auth.login(request, user)
            user.login_successful()

            # Store all user data needed by Auth view in session, this
            # way, user table does not need to be queried during the
            # performance critical request (sessions are cached).
            request.session['user_id'] = user.id
            logger.debug('%s successfully logged.' % (user.email))
            redirect_to = request.GET.get('next')
            if (redirect_to is None
                    or not url_utils.validate_redirection_target(redirect_to)):
                redirect_to = '/'

            return http.HttpResponseRedirect(request.site_url + redirect_to)

        # Return not authorized because request was well formed (400
        # doesn't seem appropriate).
        return http.HttpResponseNotAuthorized(
            _html_or_none(request, 'nothing_accessible.html'))
Exemple #3
0
    def get(self, request):
        """Invoked by the HTTP server with a single path argument.

        The HTTP server should pass the path argument verbatim,
        without any transformations or decoding. Access control
        mechanism should work on user visible paths, not paths after
        internal rewrites performed by the server.

        At the moment, the path is allowed to contain a query part,
        which is ignored (this is because nginx does not expose
        encoded path without the query part).

        The method follows be conservative in what you accept
        principle. The path should be absolute and normalized, without
        fragment id, otherwise access is denied. Browsers in normal
        operations perform path normalization and do not send fragment
        id. Multiple consecutive '/' separators are permitted, because
        these are not normalized by browsers, and are used by
        legitimate applications.  Paths with '/./' and '/../', should
        not be normally sent by browsers and can be a sign of
        something suspicious happening. It is extremely important that
        wwwhisper does not perform any path transformations that are
        not be compatible with transformations done by the HTTP
        server.
       """
        encoded_path = self._extract_encoded_path_argument(request)
        if encoded_path is None:
            return http.HttpResponseBadRequest(
                "Auth request should have 'path' argument.")

        # Do not allow requests that contain the 'User' header. The
        # header is passed to backends and must be guaranteed to be
        # set by wwwhisper.
        # This check should already be performed by HTTP server.
        if 'HTTP_USER' in request.META:
            return http.HttpResponseBadRequest(
                "Client can not set the 'User' header")

        debug_msg = "Auth request to '%s'" % (encoded_path)

        path_validation_error = None
        if url_utils.contains_fragment(encoded_path):
            path_validation_error = "Path should not include fragment ('#')"
        else:
            stripped_path = url_utils.strip_query(encoded_path)
            decoded_path = url_utils.decode(stripped_path)
            decoded_path = url_utils.collapse_slashes(decoded_path)
            if not url_utils.is_canonical(decoded_path):
                path_validation_error = 'Path should be absolute and ' \
                    'normalized (starting with / without /../ or /./ or //).'
        if path_validation_error is not None:
            logger.debug('%s: incorrect path.' % (debug_msg))
            return http.HttpResponseBadRequest(path_validation_error)

        user = _get_user(request)
        location = request.site.locations.find_location(decoded_path)
        if user is not None:

            debug_msg += " by '%s'" % (user.email)
            respone = None

            if location is not None and location.can_access(user):
                logger.debug('%s: access granted.' % (debug_msg))
                response = http.HttpResponseOK('Access granted.')
            else:
                logger.debug('%s: access denied.' % (debug_msg))
                response = http.HttpResponseNotAuthorized(
                    _html_or_none(request, 'not_authorized.html',
                                  {'email': user.email}))
            response['User'] = user.email
            return response

        if (location is not None and location.open_access_granted()
                and not location.open_access_requires_login()):
            logger.debug('%s: authentication not required, access granted.' %
                         (debug_msg))
            return http.HttpResponseOK('Access granted.')
        logger.debug('%s: user not authenticated.' % (debug_msg))
        return http.HttpResponseNotAuthenticated(
            _html_or_none(request, 'login.html', request.site.skin()))