Skip to content
Snippets Groups Projects
rproxy.py 2.44 KiB
Newer Older
# Copyright (c) 2021-2022 Neogeo-Technologies.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.


import logging

from django.conf import settings
from drfreverseproxy.views import ProxyView
from rest_framework.authentication import BasicAuthentication
from rest_framework.authentication import SessionAuthentication
from rest_framework.negotiation import DefaultContentNegotiation
from rest_framework import permissions


logger = logging.getLogger(__name__)


ONEGEOSUITE_MAPSTORE_UPSTREAM = settings.ONEGEOSUITE_MAPSTORE_UPSTREAM
ONEGEOSUITE_MAPSTORE_AUTH_HEADER = settings.ONEGEOSUITE_MAPSTORE_AUTH_HEADER


class SessionCsrfExemptAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        pass


class MapstoreProxyContentNegotiation(DefaultContentNegotiation):
    def get_accept_list(self, _):
        return ['*/*']  # Force accept all


class MapstoreProxyView(ProxyView):
    upstream = ONEGEOSUITE_MAPSTORE_UPSTREAM

    authentication_classes = [
        SessionCsrfExemptAuthentication,
        BasicAuthentication,
    ]

    permission_classes = [
        permissions.AllowAny,
    ]

    content_negotiation_class = MapstoreProxyContentNegotiation

    def get_request_headers(self):
        """
        Place le nom utilisateur dans un Header HTTP pour que Mapstore puisse
        l'autentifier. Ne positionne pas ce header si l'utilisateur est
        anonyme.

        Supprime le contenu de ce header si il existe déjà pour éviter qu'un
        attaquant externe puisse prendre l'identité d'un utilisateur.
        """
        # Les headers du META ont le prefix HTTP_ et sont en uppercase
        auth_user = 'HTTP_' + ONEGEOSUITE_MAPSTORE_AUTH_HEADER.replace('-', '_').upper()
        self.request.META.pop(auth_user, None)

        headers = super().get_request_headers()
        if not self.request.user.is_anonymous:
            headers[ONEGEOSUITE_MAPSTORE_AUTH_HEADER] = self.request.user.username

        return headers