mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #31443 -- Fixed login redirection in auth mixins when LOGIN_URL is off-site URL.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							136ec9b62b
						
					
				
				
					commit
					cc7c16af98
				
			| @@ -1,7 +1,10 @@ | ||||
| from urllib.parse import urlparse | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.contrib.auth import REDIRECT_FIELD_NAME | ||||
| from django.contrib.auth.views import redirect_to_login | ||||
| from django.core.exceptions import ImproperlyConfigured, PermissionDenied | ||||
| from django.shortcuts import resolve_url | ||||
|  | ||||
|  | ||||
| class AccessMixin: | ||||
| @@ -41,7 +44,23 @@ class AccessMixin: | ||||
|     def handle_no_permission(self): | ||||
|         if self.raise_exception or self.request.user.is_authenticated: | ||||
|             raise PermissionDenied(self.get_permission_denied_message()) | ||||
|         return redirect_to_login(self.request.get_full_path(), self.get_login_url(), self.get_redirect_field_name()) | ||||
|  | ||||
|         path = self.request.build_absolute_uri() | ||||
|         resolved_login_url = resolve_url(self.get_login_url()) | ||||
|         # If the login url is the same scheme and net location then 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 = self.request.get_full_path() | ||||
|         return redirect_to_login( | ||||
|             path, | ||||
|             resolved_login_url, | ||||
|             self.get_redirect_field_name(), | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class LoginRequiredMixin(AccessMixin): | ||||
|   | ||||
| @@ -94,6 +94,20 @@ class AccessMixinTests(TestCase): | ||||
|         self.assertEqual(response.status_code, 302) | ||||
|         self.assertEqual(response.url, '/accounts/login/?next=/rand') | ||||
|  | ||||
|     def test_access_mixin_permission_denied_remote_login_url(self): | ||||
|         class AView(AlwaysFalseView): | ||||
|             login_url = 'https://www.remote.example.com/login' | ||||
|  | ||||
|         view = AView.as_view() | ||||
|         request = self.factory.get('/rand') | ||||
|         request.user = AnonymousUser() | ||||
|         response = view(request) | ||||
|         self.assertEqual(response.status_code, 302) | ||||
|         self.assertEqual( | ||||
|             response.url, | ||||
|             'https://www.remote.example.com/login?next=http%3A//testserver/rand', | ||||
|         ) | ||||
|  | ||||
|     @mock.patch.object(models.User, 'is_authenticated', False) | ||||
|     def test_stacked_mixins_not_logged_in(self): | ||||
|         user = models.User.objects.create(username='joe', password='qwerty') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user