Esempio n. 1
0
    def __call__(self, req, form):
        """ Maybe resolve the final / of a directory """

        # When this method is called, we either are a directory which
        # has an 'index' method, and we redirect to it, or we don't
        # have such a method, in which case it is a traversal error.

        if "" in self._exports:
            if not form:
                # Fix missing trailing slash as a convenience, unless
                # we are processing a form (in which case it is better
                # to fix the form posting).
                redirect_to_url(
                    req, req.uri + "/", apache.HTTP_MOVED_PERMANENTLY)

        _debug(req, 'directory %r is not callable' % self)
        raise TraversalError()
Esempio n. 2
0
def mp_legacy_publisher(req, possible_module, possible_handler):
    """
    mod_python legacy publisher minimum implementation.
    """
    from invenio.ext.legacy.handler import CFG_HAS_HTTPS_SUPPORT, CFG_FULL_HTTPS
    if possible_module.endswith('.pyc'):
        possible_module = possible_module[:-1]
    the_module = open(possible_module).read()
    module_globals = {}
    exec(the_module, module_globals)
    if possible_handler in module_globals and callable(
            module_globals[possible_handler]):
        from invenio.ext.legacy.handler import _check_result
        ## req is the required first parameter of any handler
        expected_args = list(
            inspect.getargspec(module_globals[possible_handler])[0])
        if not expected_args or 'req' != expected_args[0]:
            ## req was not the first argument. Too bad!
            raise SERVER_RETURN, HTTP_NOT_FOUND
        ## the req.form must be casted to dict because of Python 2.4 and earlier
        ## otherwise any object exposing the mapping interface can be
        ## used with the magic **
        form = dict()
        for key, value in req.form.items():
            ## FIXME: this is a backward compatibility workaround
            ## because most of the old administration web handler
            ## expect parameters to be of type str.
            ## When legacy publisher will be removed all this
            ## pain will go away anyway :-)
            if isinstance(value, unicode):
                form[key] = value.encode('utf8')
            else:
                ## NOTE: this is a workaround for e.g. legacy webupload
                ## that is still using legacy publisher and expect to
                ## have a file (Field) instance instead of a string.
                form[key] = value

        if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT
                and session.need_https) and not req.is_https():
            from invenio_utils.url import redirect_to_url
            # We need to isolate the part of the URI that is after
            # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL.
            original_parts = urlparse(req.unparsed_uri)
            plain_prefix_parts = urlparse(CFG_SITE_URL)
            secure_prefix_parts = urlparse(CFG_SITE_SECURE_URL)

            # Compute the new path
            plain_path = original_parts[2]
            plain_path = secure_prefix_parts[2] + \
                         plain_path[len(plain_prefix_parts[2]):]

            # ...and recompose the complete URL
            final_parts = list(secure_prefix_parts)
            final_parts[2] = plain_path
            final_parts[-3:] = original_parts[-3:]

            target = urlunparse(final_parts)
            redirect_to_url(req, target)

        try:
            return _check_result(req, module_globals[possible_handler](req,
                                                                       **form))
        except TypeError as err:
            if ("%s() got an unexpected keyword argument" %
                    possible_handler) in str(err) or (
                        '%s() takes at least' % possible_handler) in str(err):
                inspected_args = inspect.getargspec(
                    module_globals[possible_handler])
                expected_args = list(inspected_args[0])
                expected_defaults = list(inspected_args[3])
                expected_args.reverse()
                expected_defaults.reverse()
                register_exception(
                    req=req,
                    prefix=
                    "Wrong GET parameter set in calling a legacy publisher handler for %s: expected_args=%s, found_args=%s"
                    % (possible_handler, repr(expected_args),
                       repr(req.form.keys())),
                    alert_admin=CFG_DEVEL_SITE)
                cleaned_form = {}
                for index, arg in enumerate(expected_args):
                    if arg == 'req':
                        continue
                    if index < len(expected_defaults):
                        cleaned_form[arg] = form.get(arg,
                                                     expected_defaults[index])
                    else:
                        cleaned_form[arg] = form.get(arg, None)
                return _check_result(
                    req, module_globals[possible_handler](req, **cleaned_form))
            else:
                raise
    else:
        raise SERVER_RETURN, HTTP_NOT_FOUND
Esempio n. 3
0
def mp_legacy_publisher(req, possible_module, possible_handler):
    """
    mod_python legacy publisher minimum implementation.
    """
    from invenio.ext.legacy.handler import CFG_HAS_HTTPS_SUPPORT, CFG_FULL_HTTPS

    if possible_module.endswith(".pyc"):
        possible_module = possible_module[:-1]
    the_module = open(possible_module).read()
    module_globals = {}
    exec(the_module, module_globals)
    if possible_handler in module_globals and callable(module_globals[possible_handler]):
        from invenio.ext.legacy.handler import _check_result

        ## req is the required first parameter of any handler
        expected_args = list(inspect.getargspec(module_globals[possible_handler])[0])
        if not expected_args or "req" != expected_args[0]:
            ## req was not the first argument. Too bad!
            raise SERVER_RETURN, HTTP_NOT_FOUND
        ## the req.form must be casted to dict because of Python 2.4 and earlier
        ## otherwise any object exposing the mapping interface can be
        ## used with the magic **
        form = dict()
        for key, value in req.form.items():
            ## FIXME: this is a backward compatibility workaround
            ## because most of the old administration web handler
            ## expect parameters to be of type str.
            ## When legacy publisher will be removed all this
            ## pain will go away anyway :-)
            if isinstance(value, unicode):
                form[key] = value.encode("utf8")
            else:
                ## NOTE: this is a workaround for e.g. legacy webupload
                ## that is still using legacy publisher and expect to
                ## have a file (Field) instance instead of a string.
                form[key] = value

        if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT and session.need_https) and not req.is_https():
            from invenio_utils.url import redirect_to_url

            # We need to isolate the part of the URI that is after
            # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL.
            original_parts = urlparse(req.unparsed_uri)
            plain_prefix_parts = urlparse(CFG_SITE_URL)
            secure_prefix_parts = urlparse(CFG_SITE_SECURE_URL)

            # Compute the new path
            plain_path = original_parts[2]
            plain_path = secure_prefix_parts[2] + plain_path[len(plain_prefix_parts[2]) :]

            # ...and recompose the complete URL
            final_parts = list(secure_prefix_parts)
            final_parts[2] = plain_path
            final_parts[-3:] = original_parts[-3:]

            target = urlunparse(final_parts)
            redirect_to_url(req, target)

        try:
            return _check_result(req, module_globals[possible_handler](req, **form))
        except TypeError as err:
            if ("%s() got an unexpected keyword argument" % possible_handler) in str(err) or (
                "%s() takes at least" % possible_handler
            ) in str(err):
                inspected_args = inspect.getargspec(module_globals[possible_handler])
                expected_args = list(inspected_args[0])
                expected_defaults = list(inspected_args[3])
                expected_args.reverse()
                expected_defaults.reverse()
                register_exception(
                    req=req,
                    prefix="Wrong GET parameter set in calling a legacy publisher handler for %s: expected_args=%s, found_args=%s"
                    % (possible_handler, repr(expected_args), repr(req.form.keys())),
                    alert_admin=CFG_DEVEL_SITE,
                )
                cleaned_form = {}
                for index, arg in enumerate(expected_args):
                    if arg == "req":
                        continue
                    if index < len(expected_defaults):
                        cleaned_form[arg] = form.get(arg, expected_defaults[index])
                    else:
                        cleaned_form[arg] = form.get(arg, None)
                return _check_result(req, module_globals[possible_handler](req, **cleaned_form))
            else:
                raise
    else:
        raise SERVER_RETURN, HTTP_NOT_FOUND
Esempio n. 4
0
    def _traverse(self, req, path, do_head=False, guest_p=True):
        """ Locate the handler of an URI by traversing the elements of
        the path."""

        _debug(req, 'traversing %r' % path)

        component, path = path[0], path[1:]

        name = self._translate(component)

        if name is None:
            obj, path = self._lookup(component, path)
        else:
            obj = getattr(self, name)

        if obj is None:
            _debug(req, 'could not resolve %s' % repr((component, path)))
            raise TraversalError()

        # We have found the next segment. If we know that from this
        # point our subpages are over HTTPS, do the switch.

        if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT and (
                self._force_https or session.need_https()
            )) and not req.is_https():
            # We need to isolate the part of the URI that is after
            # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL.
            original_parts = urlparse.urlparse(req.unparsed_uri)
            plain_prefix_parts = urlparse.urlparse(CFG_SITE_URL)
            secure_prefix_parts = urlparse.urlparse(CFG_SITE_SECURE_URL)

            # Compute the new path
            plain_path = original_parts[2]
            plain_path = secure_prefix_parts[2] + \
                plain_path[len(plain_prefix_parts[2]):]

            # ...and recompose the complete URL
            final_parts = list(secure_prefix_parts)
            final_parts[2] = plain_path
            final_parts[-3:] = original_parts[-3:]

            target = urlparse.urlunparse(final_parts)
            # The following condition used to allow certain URLs to
            # by-pass the forced SSL redirect. Since SSL certificates
            # are deployed on INSPIRE, this is no longer needed
            # Will be left here for reference.
            # from invenio.config import CFG_INSPIRE_SITE
            # if not CFG_INSPIRE_SITE or
            # plain_path.startswith('/youraccount/login'):
            redirect_to_url(req, target)

        # Continue the traversal. If there is a path, continue
        # resolving, otherwise call the method as it is our final
        # renderer. We even pass it the parsed form arguments.
        if path:
            if hasattr(obj, '_traverse'):
                return obj._traverse(req, path, do_head, guest_p)
            else:
                raise apache.SERVER_RETURN(apache.HTTP_NOT_FOUND)

        if do_head:
            req.content_type = "text/html; charset=UTF-8"
            raise apache.SERVER_RETURN(apache.DONE)

        warnings.warn("Accessed deprecated page {0.uri}".format(req),
                      PendingDeprecationWarning, stacklevel=2)
        form = req.form
        result = _check_result(req, obj(req, form))
        return result