Source code for atmo.decorators

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
from functools import wraps

from django.shortcuts import get_object_or_404
from django.utils.decorators import available_attrs
from guardian.utils import get_40x_or_None


[docs]def permission_required(perm, klass, **params): """ A decorator that will raise a 404 if an object with the given view parameters isn't found or if the request user does not have the given permission for the object. E.g. for checking if the request user is allowed to change a user with the given username:: @permission_required('auth.change_user', User) def change_user(request, username): # can use get() directly since get_object_or_404 was already called # in the decorator and would have raised a Http404 if not found user = User.objects.get(username=username) return render(request, 'change_user.html', context={'user': user}) """ ignore = params.pop('ignore', []) def decorator(view_func): @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): filters = {} for kwarg, kwvalue in list(kwargs.items()): if kwarg in ignore: continue filters[kwarg] = kwvalue obj = get_object_or_404(klass, **filters) response = get_40x_or_None( request, perms=[perm], obj=obj, return_403=True, ) if response: return response return view_func(request, *args, **kwargs) return _wrapped_view
return decorator def _full_perm(model, perm): return '%s.%s_%s' % (model._meta.app_label, perm, model._meta.model_name)
[docs]def view_permission_required(model, **params): """Checks view object permissions for the given model and parameters."""
return permission_required(_full_perm(model, 'view'), model, **params)
[docs]def add_permission_required(model, **params): """Checks add object permissions for the given model and parameters."""
return permission_required(_full_perm(model, 'add'), model, **params)
[docs]def change_permission_required(model, **params): """Checks change object permissions for the given model and parameters."""
return permission_required(_full_perm(model, 'change'), model, **params)
[docs]def delete_permission_required(model, **params): """Checks delete object permissions for the given model and parameters."""
return permission_required(_full_perm(model, 'delete'), model, **params)
[docs]def modified_date(view_func): """ A decorator that when applied to a view using a TemplateResponse will look for a context variable (by default "modified_date") to set the header (by default "X-ATMO-Modified-Date") with the ISO formatted value. This is useful to check for modification on the client side. The end result will be a header like this:: X-ATMO-Modified-Date: 2017-03-14T10:48:53+00:00 """ #: The name of the context variable context_var = 'modified_date' #: The name of the response header header = 'X-ATMO-Modified-Date' @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): response = view_func(request, *args, **kwargs) # This requires the use of TemplateResponse modified_date = getattr(response, 'context_data', {}).get(context_var) if modified_date is not None: response[header] = modified_date.isoformat() return response
return _wrapped_view