Skip to content

Commit

Permalink
Temporary custom middleware for django-termsandconditions, to support…
Browse files Browse the repository at this point in the history
… passing querystring onward (for using Django as an authentication mechanism for external services). Shall be removed once django-termsandconditions supports the same functionality.
  • Loading branch information
helgihg committed Nov 23, 2018
1 parent 65c2d5d commit 9c943b7
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
84 changes: 84 additions & 0 deletions core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,87 @@ def process_response(self, request, response):

return response
return response


# This middleware is hopefully temporary. The vanilla
# TermsAndConditionsRedirectMiddleware currently does not support passing the
# URL's querystring onward. This means that an external service, using Django
# as an authentication mechanism, will not receive its token back from the
# login process if the terms and service need to be agreed to by the user.
# This custom replacement, which is hopefully temporary, is a self-contained
# and slightly refactored version of the vanilla
# TermsAndConditionsRedirectMiddleware from django-termsandconditions version
# 1.2.8.
#
# The fix we needed is adding the querystring in the "for term in
# TermsAndConditions..." loop. The same change has already been proposed as a
# pull request to its author:
# https://github.com/cyface/django-termsandconditions/pull/75
#
# TODO: Once the problem has been fixed in the official version of
# django-termsandconditions, this entire class and its preceding import lines
# should be removed, its mention in settings.py should be set to the official
# package's edition. No further changes should be necessary to deprecate it.
from termsandconditions.models import TermsAndConditions
from termsandconditions.pipeline import redirect_to_terms_accept
class CustomTermsAndConditionsRedirectMiddleware():
"""
This middleware checks to see if the user is logged in, and if so,
if they have accepted all the active terms.
"""

def process_request(self, request):
"""Process each request to app to ensure terms have been accepted"""

current_path = request.META['PATH_INFO']

user_authenticated = request.user.is_authenticated()

if user_authenticated and self.is_path_protected(current_path):
for term in TermsAndConditions.get_active_terms_not_agreed_to(request.user):
# Check for querystring and include it if there is one
qs = request.META['QUERY_STRING']
current_path += '?' + qs if qs else ''
return redirect_to_terms_accept(current_path, term.slug)

return None

def is_path_protected(self, path):
"""
returns True if given path is to be protected, otherwise False
The path is not to be protected when it appears on:
TERMS_EXCLUDE_URL_PREFIX_LIST, TERMS_EXCLUDE_URL_LIST or as
ACCEPT_TERMS_PATH
"""
protected = True

ACCEPT_TERMS_PATH = getattr(
settings,
'ACCEPT_TERMS_PATH',
'/terms/accept/'
)

TERMS_EXCLUDE_URL_PREFIX_LIST = getattr(
settings,
'TERMS_EXCLUDE_URL_PREFIX_LIST',
{'/admin', '/terms'}
)

TERMS_EXCLUDE_URL_LIST = getattr(
settings,
'TERMS_EXCLUDE_URL_LIST',
{'/', '/termsrequired/', '/logout/', '/securetoo/'}
)

for exclude_path in TERMS_EXCLUDE_URL_PREFIX_LIST:
if path.startswith(exclude_path):
protected = False

if path in TERMS_EXCLUDE_URL_LIST:
protected = False

if path.startswith(ACCEPT_TERMS_PATH):
protected = False

return protected
2 changes: 1 addition & 1 deletion wasa2il/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
'django.middleware.cache.FetchFromCacheMiddleware',
'core.middleware.GlobalsMiddleware',
'core.middleware.AutoLogoutMiddleware',
'termsandconditions.middleware.TermsAndConditionsRedirectMiddleware',
'core.middleware.CustomTermsAndConditionsRedirectMiddleware',
'core.middleware.SamlMiddleware',
)
try:
Expand Down

0 comments on commit 9c943b7

Please sign in to comment.