示例#1
0
文件: views.py 项目: maanas/wwwhisper
    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. Not normalized paths can be a sign of something
        suspicious happening. It is extremely important that
        wwwhisper does not perform any tricky path transformations
        that may 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.")
        debug_msg = "Auth request to '%s'" % (encoded_path)

        path_validation_error = None
        if url_path.contains_fragment(encoded_path):
            path_validation_error = "Path should not include fragment ('#')"
        else:
            stripped_path = url_path.strip_query(encoded_path)
            decoded_path = url_path.decode(stripped_path)
            if not url_path.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 = request.user
        location = self.locations_collection.find_location(decoded_path)

        if user and user.is_authenticated():
            debug_msg += " by '%s'" % (user.email)

            if location is not None and location.can_access(user.uuid):
                logger.debug('%s: access granted.' % (debug_msg))
                return http.HttpResponseOK('Access granted.')
            logger.debug('%s: access denied.' % (debug_msg))
            return http.HttpResponseNotAuthorized()

        if location is not None and location.open_access:
            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()
示例#2
0
文件: models.py 项目: viciu/wwwhisper
    def create_item(self, path):
        """Creates a new Location object.

        The location path should be canonical and should not contain
        parts that are not used for access control (query, fragment,
        parameters). Location should not contain non-ascii characters.

        Args:
            path: A canonical path to the location.

        Raises:
            CreationException if the path is invalid or if a location
            with such path already exists.
        """

        if not url_path.is_canonical(path):
            raise CreationException(
                'Path should be absolute and normalized (starting with / '\
                    'without /../ or /./ or //).')
        if url_path.contains_fragment(path):
            raise CreationException(
                "Path should not contain fragment ('#' part).")
        if url_path.contains_query(path):
            raise CreationException(
                "Path should not contain query ('?' part).")
        if url_path.contains_params(path):
            raise CreationException(
                "Path should not contain parameters (';' part).")
        try:
            if path.encode('utf-8', 'strict') != path:
                raise CreationException(
                    'Path should contain only ascii characters.')
        except UnicodeError:
            raise CreationException('Invalid path encoding')

        if _find(Location, path=path) is not None:
            raise CreationException('Location already exists.')
        location = Location.objects.create(path=path)
        location.save()
        return location
示例#3
0
    def test_is_canonical(self):
        self.assertTrue(is_canonical("/"))
        self.assertTrue(is_canonical("/foo/bar"))
        self.assertTrue(is_canonical("/foo/bar/"))
        self.assertTrue(is_canonical("/foo/bar/  "))

        self.assertFalse(is_canonical(""))
        self.assertFalse(is_canonical("foo"))
        self.assertFalse(is_canonical("//"))
        self.assertFalse(is_canonical(" /"))
        self.assertFalse(is_canonical(" //"))
        self.assertFalse(is_canonical("//foo"))
        self.assertFalse(is_canonical("/foo/bar/.."))
        self.assertFalse(is_canonical("/foo//bar"))
        self.assertFalse(is_canonical("/foo/bar//"))
        self.assertFalse(is_canonical("/foo/bar/./foo"))