def apply()

in Allura/allura/lib/patches.py [0:0]


def apply():
    global _patched  # noqa: PLW0603
    if _patched:
        return
    _patched = True

    old_lookup_template_engine = tg.decorators.Decoration.lookup_template_engine

    @h.monkeypatch(tg.decorators.Decoration)
    def lookup_template_engine(self, request):
        '''Wrapper to handle totally borked-up HTTP-ACCEPT headers'''
        try:
            return old_lookup_template_engine(self, request)
        except Exception:
            pass
        environ = dict(request.environ, HTTP_ACCEPT='*/*')
        request = webob.Request(environ)
        return old_lookup_template_engine(self, request)

    @h.monkeypatch(tg, tg.decorators)
    def override_template(controller, template):
        '''Copy-pasted patch to allow multiple colons in a template spec'''
        if hasattr(controller, 'decoration'):
            decoration = controller.decoration
        else:
            return
        if hasattr(decoration, 'engines'):
            engines = decoration.engines
        else:
            return

        for content_type, content_engine in engines.items():
            template = template.split(':', 1)
            template.extend(content_engine[2:])
            try:
                override_mapping = request._override_mapping
            except AttributeError:
                override_mapping = request._override_mapping = {}
            override_mapping[controller.__func__] = {content_type: template}

    @h.monkeypatch(tg, tg.decorators)
    @decorator
    def without_trailing_slash(func, *args, **kwargs):
        '''Monkey-patched to use 301 redirects for SEO, and handle query strings'''
        __traceback_hide__ = 'before_and_this'  # for paste/werkzeug shorter traces
        response_type = getattr(request, 'response_type', None)
        if (request.method == 'GET' and request.path.endswith('/') and not response_type):
            location = request.path_url[:-1]
            if request.query_string:
                location += '?' + request.query_string
            raise webob.exc.HTTPMovedPermanently(location=location)
        return func(*args, **kwargs)

    @h.monkeypatch(tg, tg.decorators)
    @decorator
    def with_trailing_slash(func, *args, **kwargs):
        '''Monkey-patched to use 301 redirects for SEO, and handle query strings'''
        __traceback_hide__ = 'before_and_this'  # for paste/werkzeug shorter traces
        response_type = getattr(request, 'response_type', None)
        if (request.method == 'GET' and not request.path.endswith('/') and not response_type):
            location = request.path_url + '/'
            if request.query_string:
                location += '?' + request.query_string
            raise webob.exc.HTTPMovedPermanently(location=location)
        return func(*args, **kwargs)

    # http://blog.watchfire.com/wfblog/2011/10/json-based-xss-exploitation.html
    # change < to its unicode escape when rendering JSON out of turbogears
    # This is to avoid IE9 and earlier, which don't know the json content type
    # and may attempt to render JSON data as HTML if the URL ends in .html
    original_tg_jsonify_JSONEncoder_encode = tg.jsonify.JSONEncoder.encode

    @h.monkeypatch(tg.jsonify.JSONEncoder)
    def encode(self, o):
        return original_tg_jsonify_JSONEncoder_encode(self, o).replace('<', r'\u003C')