Source code for annotator_store.utils

from functools import wraps

from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.sites.models import Site
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.shortcuts import resolve_url
from django.template import RequestContext
from django.template.loader import get_template
from django.utils.decorators import available_attrs
from django.utils.six.moves.urllib.parse import urlparse



[docs]def absolutize_url(local_url): '''Convert a local url to an absolute url, with scheme and server name, based on the current configured :class:`~django.contrib.sites.models.Site`. :param local_url: local url to be absolutized, e.g. something generated by :meth:`~django.core.urlresolvers.reverse` ''' if local_url.startswith('https'): return local_url # add scheme and server (i.e., the http://example.com) based # on the django Sites infrastructure. root = Site.objects.get_current().domain # but also add the http:// if necessary, since most sites docs # suggest using just the domain name if not root.startswith('https'): root = 'https://' + root # make sure there is no double slash between site url and local url if local_url.startswith('/'): root = root.rstrip('/') return root + local_url
[docs]def user_passes_test_ajax_403(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): '''Variation on :meth:`django.contrib.auth.decorators.user_passes_test`. If the user is already logged in but has insufficient privileges, returns a 403 Forbidden response because redirecting to log in is not useful. If request is ajax user is not authenticated, returns a 401 because redirecting an ajax request to login is also not useful. Partially adapted from/inspired by :mod:`eulcommon` implementation. http://eulcommon.readthedocs.io/en/0.17.0/djangoextras.html#module-eulcommon.djangoextras.auth ''' def decorator(view_func): @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): # if test passes, return view normally if test_func(request.user): return view_func(request, *args, **kwargs) # if user is authenticated, default django behavior of # redirecting to login page is not useful if request.user.is_authenticated(): raise PermissionDenied # if user is not authenticated, check for ajax request # (redirect to login also not useful for ajax) if request.is_ajax(): # send 403 Forbidden response resp = HttpResponse('Not Authorized') resp.status_code = 401 return resp # otherwise redirect normally # (default user_passes_test logic from django) path = request.build_absolute_uri() resolved_login_url = resolve_url(login_url or settings.LOGIN_URL) # If the login url is the same scheme and net location then just # use the path as the "next" url. login_scheme, login_netloc = urlparse(resolved_login_url)[:2] current_scheme, current_netloc = urlparse(path)[:2] if ((not login_scheme or login_scheme == current_scheme) and (not login_netloc or login_netloc == current_netloc)): path = request.get_full_path() from django.contrib.auth.views import redirect_to_login return redirect_to_login( path, resolved_login_url, redirect_field_name) return _wrapped_view return decorator
[docs]def permission_required(perm, login_url=None): '''Version of :meth:`django.contrib.auth.decorators.permission_required` that uses :meth:`user_passes_test_with_ajax_403` for better http response codes and ajax handling.''' return user_passes_test_ajax_403(lambda u: u.has_perm(perm), login_url=login_url)