diff --git a/src/pretix/api/auth/session.py b/src/pretix/api/auth/session.py new file mode 100644 index 0000000000..cf55f87cf4 --- /dev/null +++ b/src/pretix/api/auth/session.py @@ -0,0 +1,47 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from rest_framework import exceptions +from rest_framework.authentication import SessionAuthentication as BaseSessionAuthentication + +from pretix.multidomain.middlewares import CsrfViewMiddleware + + +class CustomCSRFCheck(CsrfViewMiddleware): + def _reject(self, request, reason): + # Return the failure reason instead of an HttpResponse + return reason + + +class SessionAuthentication(BaseSessionAuthentication): + # Override from DRF to user our custom CSRF middleware + + def enforce_csrf(self, request): + def dummy_get_response(request): # pragma: no cover + return None + + check = CustomCSRFCheck(dummy_get_response) + # populates request.META['CSRF_COOKIE'], which is used in process_view() + check.process_request(request) + reason = check.process_view(request, None, (), {}) + if reason: + # CSRF failed, bail with explicit error message + raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)