Source code for auth_functional

# -*- coding: utf-8 -*-
from functools import wraps

from django.http import HttpResponse, HttpRequest
from django.conf import settings
from django.core import urlresolvers
from django.contrib.auth.decorators import login_required as django_login_required


def DEFAULT_AUTHENTICATOR(*args, **kwargs):
    return not django_login_required(*args, **kwargs)


class Unauthorized(HttpResponse):
    status_code = 401


def unauthorized_response(*args, **kwargs):
    return Unauthorized()


class Forbidden(HttpResponse):
    status_code = 403


def forbidden_response(*args, **kwargs):
    return Forbidden()


def cleaned_args(args):
    if args and not isinstance(args[0], HttpRequest):
        return args[1:]
    return args


[docs]def authentication(view=None, authenticator=None, www_authenticate=None, response_factory=None): """Check request's authentication. :param view: View or class-based view to decorate. :param authenticator: Callable that checks request's authentication. If `None` the default method: `DEFAULT_AUTHENTICATOR` is used. The callable is passed the request along with args/kwargs passed by the dispatcher. :param www_authenticate: Header to send in the response as a request to the client to authenticate if the authentication failed. :param response_factory: Callable to use for building the response. Useful if you want to prepare the response yourself. The callable is passed the request along with args/kwargs passed by the dispatcher. :return: HTTP 401 "Unauthorized" response if the authentication failed, otherwise the response returned by the decorated view. """ if authenticator is None: authenticator = DEFAULT_AUTHENTICATOR if response_factory is None: response_factory = unauthorized_response def wrapper(view): @wraps(view) def decorator(*args, **kwargs): if authenticator(*cleaned_args(args), **kwargs): return view(*args, **kwargs) response = response_factory(*args, **kwargs) if www_authenticate is not None: response["WWW-Authenticate"] = www_authenticate return response return decorator if view is not None: wrapper = wrapper(view) return wrapper
[docs]def authorization(condition, response_factory=None): """Check request's authorization. :param condition: Callable that returns `True` if the request is authorized and `False` otherwise. The callable is passed the request along with args/kwargs passed by the dispatcher. :param response_factory: Callable to use for building the response. Useful if you want to prepare the response yourself. The callable is passed the request along with args/kwargs passed by the dispatcher. :return: HTTP 403 "Forbidden" response if the authorization failed, otherwise the response returned by the decorated view. """ if response_factory is None: response_factory = forbidden_response def wrapper(view): @wraps(view) def decorator(*args, **kwargs): if condition(*cleaned_args(args), **kwargs): return view(*args, **kwargs) return response_factory(*args, **kwargs) return decorator return wrapper
[docs]def or_(*conditions): """Decorator that takes multiple condition functions and returns `True` if one is `True`. :param conditions: Multiple condition functions. """ def decorator(*args, **kwargs): args = cleaned_args(args) return any(condition(*args, **kwargs) for condition in conditions) return decorator
[docs]def and_(*conditions): """Decorator that takes multiple condition functions and the if one is `False` returns `False`. :param conditions: Multiple condition functions. """ def decorator(*args, **kwargs): args = cleaned_args(args) return all(condition(*args, **kwargs) for condition in conditions) return decorator
[docs]def not_(condition): """Decorator that takes a condition and negates its return value. :param conditions: Condition function. """ def decorator(*args, **kwargs): args = cleaned_args(args) return not condition(*args, **kwargs) return decorator
[docs]class RequestFixtureMiddleware(object): """Middleware that sets a fixture object with registered fixture functions as methods.""" def process_request(self, request): type(request).cache = DictCacheDescriptor() type(request).fixtures = FixtureDescriptor()
class DictCacheDescriptor(object): def __init__(self, cache=None): if cache is None: cache = {} self.cache = cache def __get__(self, request, type=None): return self.cache class FixtureDescriptor(object): def __get__(self, request, type=None): return FixtureAccessor(fixtures, request, request.cache) class FixtureAccessor(object): def __init__(self, fixtures, request, cache): self.fixtures = fixtures self.request = request self.cache = cache def __getattr__(self, name): if name in self.cache: result = self.cache[name] else: view_args, view_kwargs = self.get_resolver_args_and_kwargs() result = self.fixtures.get(name)(*view_args, **view_kwargs) self.cache[name] = result return result def get_resolver_args_and_kwargs(self): if hasattr(self.request, 'resolver_match'): _, args, kwargs = self.request.resolver_match else: urlconf = getattr(self.request, 'urlconf', settings.ROOT_URLCONF) urlresolvers.set_urlconf(urlconf) resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) _, args, kwargs = resolver.resolve(self.request.path_info) return args, kwargs class Fixtures(object): def __init__(self): self._register = {} def __getattr__(self, name): if name not in self._register: raise AttributeError('{!r} object has not attribute {!r}'.format(type(self), name)) return self._register[name] def register(self, name, f): self._register[name] = f def get(self, name, default=None): return self._register.get(name, default) fixtures = Fixtures() register_fixture = fixtures.register