| import urlparse |
| try: |
| from functools import wraps |
| except ImportError: |
| from django.utils.functional import wraps # Python 2.4 fallback. |
| |
| from django.conf import settings |
| from django.contrib.auth import REDIRECT_FIELD_NAME |
| from django.utils.decorators import available_attrs |
| |
| |
| def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): |
| """ |
| Decorator for views that checks that the user passes the given test, |
| redirecting to the log-in page if necessary. The test should be a callable |
| that takes the user object and returns True if the user passes. |
| """ |
| |
| def decorator(view_func): |
| @wraps(view_func, assigned=available_attrs(view_func)) |
| def _wrapped_view(request, *args, **kwargs): |
| if test_func(request.user): |
| return view_func(request, *args, **kwargs) |
| path = request.build_absolute_uri() |
| # 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.urlparse(login_url or |
| settings.LOGIN_URL)[:2] |
| current_scheme, current_netloc = urlparse.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, login_url, redirect_field_name) |
| return _wrapped_view |
| return decorator |
| |
| |
| def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): |
| """ |
| Decorator for views that checks that the user is logged in, redirecting |
| to the log-in page if necessary. |
| """ |
| actual_decorator = user_passes_test( |
| lambda u: u.is_authenticated(), |
| login_url=login_url, |
| redirect_field_name=redirect_field_name |
| ) |
| if function: |
| return actual_decorator(function) |
| return actual_decorator |
| |
| |
| def permission_required(perm, login_url=None): |
| """ |
| Decorator for views that checks whether a user has a particular permission |
| enabled, redirecting to the log-in page if necessary. |
| """ |
| return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url) |