Proxy

Proxy decorators are used to tag and register functions with a global mechanism. For instance, a security layer that protects access to the code, depending on the current user, can be implemented using a centralized checker with an associated permission required by the callable:

class User(object): 
    def __init__(self, roles): 
        self.roles = roles 
 
 
class Unauthorized(Exception): 
    pass 
 
 
def protect(role): 
    def _protect(function): 
        def __protect(*args, **kw): 
            user = globals().get('user') 
            if user is None or role not in user.roles: 
                raise Unauthorized("I won't tell you") 
            return function(*args, **kw) 
        return __protect 
    return _protect

This model is often used in Python web frameworks to define the security over publishable resources. For instance, Django provides decorators to secure its access to views representing web resources.

Here's an example, where the current user is kept in a global variable. The decorator checks his or her roles when the method is accessed (the previous snippet is stored in the users module):

>>> from users import User, protect
>>> tarek = User(('admin', 'user'))
>>> bill = User(('user',)) >>> class RecipeVault(object): ... @protect('admin') ... def get_waffle_recipe(self): ... print('use tons of butter!') ... >>> my_vault = RecipeVault() >>> user = tarek >>> my_vault.get_waffle_recipe() use tons of butter! >>> user = bill >>> my_vault.get_waffle_recipe() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in wrap __main__.Unauthorized: I won't tell you