Simple Age Verification Middleware

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
age_verification.py:

class AgeVerificationMiddleware(object):
  """
  Sets the age_verified request.user attribute 
  """
  def process_request(self, request):
      """sets the age_verified request.user attribute"""
      request.user.__class__.is_age_verified = AgeVerification(request.session)
      return None
    
class AgeVerification:
    def __init__(self, session):
        self.session = session
        self.SESSION_VARIABLE = '_age_verified'

    def __call__(self):
        return self._get()

    def _get(self):
        return self.session.get(self.SESSION_VARIABLE, [])

    def verify(self):
        """
        sets the session flag, determining age verification
        """
        self.session[self.SESSION_VARIABLE] = True

decorators.py:

try:
    from functools import update_wrapper
except ImportError:
    from django.utils.functional import update_wrapper  # Python 2.3, 2.4 fallback.

from django.http import HttpResponseRedirect
from django.utils.http import urlquote

REDIRECT_FIELD_NAME = "next"

def user_passes_test(test_func, verify_age_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user passes the given test,
    redirecting to the age verification page if necessary. The test should be a callable
    that takes the user object and returns True if the user passes.
    """
    def decorate(view_func):
        return _CheckAgeVerification(view_func, test_func, verify_age_url, redirect_field_name)
    return decorate

def age_verification_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user is age verified, redirecting
    to the age verification page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_age_verified(),
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

class _CheckAgeVerification(object):
    """    
    Class that checks that the user passes the given test, redirecting to
    the age verification page if necessary. If the test is passed, the view function
    is invoked. The test should be a callable that takes the user object
    and returns True if the user passes.

    We use a class here so that we can define __get__. This way, when a
    _CheckAgeVerification object is used as a method decorator, the view function
    is properly bound to its instance.
    
    Modeled after django.auth.decorators to be consistent
    """
    def __init__(self, view_func, test_func, verify_age_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
        if not verify_age_url:
            from django.conf import settings
            verify_age_url = settings.VERIFY_AGE_URL
        self.view_func = view_func
        self.test_func = test_func
        self.verify_age_url = verify_age_url
        self.redirect_field_name = redirect_field_name
        update_wrapper(self, view_func)
        
    def __get__(self, obj, cls=None):
        view_func = self.view_func.__get__(obj, cls)
        return _CheckAgeVerification(view_func, self.test_func, self.verify_age_url, self.redirect_field_name)
    
    def __call__(self, request, *args, **kwargs):
        if self.test_func(request.user):
            return self.view_func(request, *args, **kwargs)
        path = urlquote(request.get_full_path())
        tup = self.verify_age_url, self.redirect_field_name, path
        return HttpResponseRedirect('%s?%s=%s' % tup)

More like this

  1. Auto rendering decorator with options by Batiste 6 years, 2 months ago
  2. render_to by asolovyov 5 years, 9 months ago
  3. Get the referer view of a request by arthurfurlan 4 years, 11 months ago
  4. Generic AJAX app by Rupe 4 years, 9 months ago
  5. render_with decorator by tobias 5 years, 7 months ago

Comments

(Forgotten your password?)