automatic reload on lists; new django decorator for ajax request
[osm/LW-UI.git] / sf_t3d / decorators.py
1 #
2 # Copyright 2018 EveryUP Srl
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17 """
18 This Decorator is a modified version of django.contrib.auth.decorators, in order to avoid retirect to login_url
19 with AJAX calls.
20 """
21
22 from django.http import HttpResponse
23 from django.conf import settings
24 from django.contrib.auth import REDIRECT_FIELD_NAME
25 from django.shortcuts import resolve_url
26 from django.utils.decorators import available_attrs
27 from django.utils.six.moves.urllib.parse import urlparse
28 from six import wraps
29 from django.contrib.auth.views import redirect_to_login
30
31
32 def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
33 """
34 Decorator for views that checks that the user passes the given test,
35 redirecting to the log-in page if necessary. The test should be a callable
36 that takes the user object and returns True if the user passes.
37 """
38
39 def decorator(view_func):
40 @wraps(view_func, assigned=available_attrs(view_func))
41 def _wrapped_view(request, *args, **kwargs):
42 if test_func(request.user):
43 return view_func(request, *args, **kwargs)
44 path = request.build_absolute_uri()
45 resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
46 # If the login url is the same scheme and net location then just
47 # use the path as the "next" url.
48 login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
49 current_scheme, current_netloc = urlparse(path)[:2]
50 if ((not login_scheme or login_scheme == current_scheme) and
51 (not login_netloc or login_netloc == current_netloc)):
52 path = request.get_full_path()
53 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
54 # if Browser call
55 if 'application/json' not in raw_content_types:
56 return redirect_to_login(path, resolved_login_url, redirect_field_name)
57 # if AJAX call
58 else:
59 return HttpResponse(status=401)
60 return _wrapped_view
61 return decorator
62
63
64 def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
65 """
66 Decorator for views that checks that the user is logged in, redirecting
67 to the log-in page if necessary.
68 """
69 actual_decorator = user_passes_test(
70 lambda u: u.is_authenticated,
71 login_url=login_url,
72 redirect_field_name=redirect_field_name
73 )
74 if function:
75 return actual_decorator(function)
76 return actual_decorator