def _get_login_redirect_url(request, redirect_to):
# Ensure the user-originating redirection URL is safe.
if not is_safe_url(url=redirect_to, host=request.get_host()):
return resolve_url(settings.LOGIN_REDIRECT_URL)
return redirect_to
python类resolve_url()的实例源码
def logout(request, next_page=None,
template_name='registration/logged_out.html',
redirect_field_name=REDIRECT_FIELD_NAME,
extra_context=None):
"""
Logs out the user and displays 'You are logged out' message.
"""
auth_logout(request)
if next_page is not None:
next_page = resolve_url(next_page)
elif settings.LOGOUT_REDIRECT_URL:
next_page = resolve_url(settings.LOGOUT_REDIRECT_URL)
if (redirect_field_name in request.POST or
redirect_field_name in request.GET):
next_page = request.POST.get(redirect_field_name,
request.GET.get(redirect_field_name))
# Security check -- don't allow redirection to a different host.
if not is_safe_url(url=next_page, host=request.get_host()):
next_page = request.path
if next_page:
# Redirect to this page until the session has been cleared.
return HttpResponseRedirect(next_page)
current_site = get_current_site(request)
context = {
'site': current_site,
'site_name': current_site.name,
'title': _('Logged out')
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context)
def logout_then_login(request, login_url=None, extra_context=None):
"""
Logs out the user if they are logged in. Then redirects to the log-in page.
"""
if not login_url:
login_url = settings.LOGIN_URL
login_url = resolve_url(login_url)
return logout(request, login_url, extra_context=extra_context)
def password_reset(request,
template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
subject_template_name='registration/password_reset_subject.txt',
password_reset_form=PasswordResetForm,
token_generator=default_token_generator,
post_reset_redirect=None,
from_email=None,
extra_context=None,
html_email_template_name=None,
extra_email_context=None):
if post_reset_redirect is None:
post_reset_redirect = reverse('password_reset_done')
else:
post_reset_redirect = resolve_url(post_reset_redirect)
if request.method == "POST":
form = password_reset_form(request.POST)
if form.is_valid():
opts = {
'use_https': request.is_secure(),
'token_generator': token_generator,
'from_email': from_email,
'email_template_name': email_template_name,
'subject_template_name': subject_template_name,
'request': request,
'html_email_template_name': html_email_template_name,
'extra_email_context': extra_email_context,
}
form.save(**opts)
return HttpResponseRedirect(post_reset_redirect)
else:
form = password_reset_form()
context = {
'form': form,
'title': _('Password reset'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context)
def password_reset_complete(request,
template_name='registration/password_reset_complete.html',
extra_context=None):
context = {
'login_url': resolve_url(settings.LOGIN_URL),
'title': _('Password reset complete'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context)
def password_change(request,
template_name='registration/password_change_form.html',
post_change_redirect=None,
password_change_form=PasswordChangeForm,
extra_context=None):
if post_change_redirect is None:
post_change_redirect = reverse('password_change_done')
else:
post_change_redirect = resolve_url(post_change_redirect)
if request.method == "POST":
form = password_change_form(user=request.user, data=request.POST)
if form.is_valid():
form.save()
# Updating the password logs out all other sessions for the user
# except the current one.
update_session_auth_hash(request, form.user)
return HttpResponseRedirect(post_change_redirect)
else:
form = password_change_form(user=request.user)
context = {
'form': form,
'title': _('Password change'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context)
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()
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
def get_success_url(self):
"""Ensure the user-originating redirection URL is safe."""
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, '')
)
url_is_safe = is_safe_url(
url=redirect_to,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
if not url_is_safe:
return resolve_url(settings.LOGIN_REDIRECT_URL)
return redirect_to
def logout_then_login(request, login_url=None, extra_context=_sentinel):
"""
Logs out the user if they are logged in. Then redirects to the log-in page.
"""
if extra_context is not _sentinel:
warnings.warn(
"The unused `extra_context` parameter to `logout_then_login` "
"is deprecated.", RemovedInDjango21Warning
)
if not login_url:
login_url = settings.LOGIN_URL
login_url = resolve_url(login_url)
return LogoutView.as_view(next_page=login_url)(request)
def get_context_data(self, **kwargs):
context = super(PasswordResetCompleteView, self).get_context_data(**kwargs)
context['login_url'] = resolve_url(settings.LOGIN_URL)
return context
def password_change(request,
template_name='registration/password_change_form.html',
post_change_redirect=None,
password_change_form=PasswordChangeForm,
extra_context=None):
warnings.warn("The password_change() view is superseded by the "
"class-based PasswordChangeView().",
RemovedInDjango21Warning, stacklevel=2)
if post_change_redirect is None:
post_change_redirect = reverse('password_change_done')
else:
post_change_redirect = resolve_url(post_change_redirect)
if request.method == "POST":
form = password_change_form(user=request.user, data=request.POST)
if form.is_valid():
form.save()
# Updating the password logs out all other sessions for the user
# except the current one.
update_session_auth_hash(request, form.user)
return HttpResponseRedirect(post_change_redirect)
else:
form = password_change_form(user=request.user)
context = {
'form': form,
'title': _('Password change'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context)
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()
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
def logout(request):
auth_logout(request)
return redirect(resolve_url('home'))
def _should_abort_user(request, should_redirect):
# authorize if user is staff
if request.user.is_staff:
return False
# authorize if user is female and not blocked
not_female = False
blocked = False
if hasattr(request.user, 'profile'):
if request.user.profile.gender == Profile.FEMALE:
if not request.user.profile.blocked:
return False
else:
blocked = True
else:
not_female = True
auth_logout(request)
if should_redirect:
if not_female:
return redirect(resolve_url('female_only'))
elif blocked:
return redirect(resolve_url('blocked'))
return HttpResponseForbidden()
def _affiliation_to_dict(affiliation):
return dict(url=resolve_url('app:chat', affiliation.chat.hash_id),
key=affiliation.hash_id,
alias=affiliation.alias,
active=affiliation.active,
valentinas=affiliation.chat.affiliation_set.count())
def setUp(self):
# handle user and chat database objects
user_data = {'password': self.PASSWORD}
self.user = User.objects.create_user(self.USERNAME, **user_data)
self.chat = Chat.objects.first()
profile_data = {'user': self.user, 'nickname': self.NICKNAME,
'gender': Profile.FEMALE}
self.profile = Profile.objects.create(**profile_data)
affiliation_data = {'chat': self.chat, 'user': self.user,
'alias': self.CHAT_ALIAS}
self.affiliation = Affiliation.objects.create(**affiliation_data)
self.message = Message.objects.first()
# list all URLs, their allowed methods, and the required data
self.cases = ({'url': resolve_url('app:chat', self.chat.hash_id),
'allowed_methods': ('get', 'post'),
'data': {'content': 'Hey', 'chat': self.chat.hash_id}},
{'url': resolve_url('app:profile'),
'allowed_methods': ('post'),
'data': {'nickname': 'Olivia'}},
{'url': resolve_url('app:affiliation'),
'allowed_methods': ('post'),
'data': {'alias': 'Guy', 'person': '4'}},
{'url': resolve_url('app:report'),
'allowed_methods': ('post'),
'data': {'pk': self.message.hash_id}})
# set main vars for HTTP request tests
self.ajax_header = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
self.methods = {'get': self.client.get,
'post': self.client.post,
'put': self.client.put,
'patch': self.client.patch,
'delete': self.client.delete}
def test_requests_without_login(self):
"""
All methods should redirect to login page when user is not logged in
"""
requests = self.get_all_requests()
for url, method, allowed, resp, ajax in requests:
with self.subTest():
expected = '{}?next={}'.format(resolve_url('home'), url)
self.assertRedirects(resp, expected)
def setUp(self):
# create user with password and affiliate her to a chatroom
self.user = User.objects.create_user('valentinavc', password='valentina')
self.chat = Chat.objects.first()
Profile.objects.create(user=self.user, gender=Profile.FEMALE, nickname='valanon')
Affiliation.objects.create(chat=self.chat, user=self.user, alias='Geek')
# login and POST
self.login = self.client.login(username='valentinavc',
password='valentina')
data = {'content': 'Hello, world', 'chat': self.chat.pk}
self.resp = self.client.post(resolve_url('app:chat', self.chat.hash_id),
data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
def setUp(self):
User.objects.create_user('olivia', password='password')
self.client.login(username='olivia', password='password')
self.resp = self.client.get(resolve_url('app:logout'))