prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Bug - Redirect loop
  There seems to be a bug of redirection loop when a user (created without any admin/editor roles) attempts to log in. I was trying out the demo and apparently the admin interface does not cater for users without any roles.
  
  It would be nice to know if there is a workaround this issue. Thanks!
  
  
  </issue>
  <code>
  [start of wagtail/wagtailadmin/views/account.py]
  1 from django.conf import settings
  2 from django.shortcuts import render, redirect
  3 from django.contrib import messages
  4 from django.contrib.auth.forms import SetPasswordForm
  5 from django.contrib.auth.decorators import permission_required
  6 from django.contrib.auth.views import logout as auth_logout, login as auth_login
  7 from django.utils.translation import ugettext as _ 
  8 from django.views.decorators.debug import sensitive_post_parameters
  9 from django.views.decorators.cache import never_cache
  10 
  11 from wagtail.wagtailadmin import forms
  12 from wagtail.wagtailusers.forms import NotificationPreferencesForm
  13 from wagtail.wagtailusers.models import UserProfile
  14 from wagtail.wagtailcore.models import UserPagePermissionsProxy
  15 
  16 
  17 @permission_required('wagtailadmin.access_admin')
  18 def account(request):
  19     user_perms = UserPagePermissionsProxy(request.user)
  20     show_notification_preferences = user_perms.can_edit_pages() or user_perms.can_publish_pages()
  21 
  22     return render(request, 'wagtailadmin/account/account.html', {
  23         'show_change_password': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True) and request.user.has_usable_password(),
  24         'show_notification_preferences': show_notification_preferences
  25     })
  26 
  27 
  28 @permission_required('wagtailadmin.access_admin')
  29 def change_password(request):
  30     can_change_password = request.user.has_usable_password()
  31 
  32     if can_change_password:
  33         if request.POST:
  34             form = SetPasswordForm(request.user, request.POST)
  35 
  36             if form.is_valid():
  37                 form.save()
  38 
  39                 messages.success(request, _("Your password has been changed successfully!"))
  40                 return redirect('wagtailadmin_account')
  41         else:
  42             form = SetPasswordForm(request.user)
  43     else:
  44         form = None
  45 
  46     return render(request, 'wagtailadmin/account/change_password.html', {
  47         'form': form,
  48         'can_change_password': can_change_password,
  49     })
  50 
  51 
  52 @permission_required('wagtailadmin.access_admin')
  53 def notification_preferences(request):
  54 
  55     if request.POST:
  56         form = NotificationPreferencesForm(request.POST, instance=UserProfile.get_for_user(request.user))
  57 
  58         if form.is_valid():
  59             form.save()
  60             messages.success(request, _("Your preferences have been updated successfully!"))
  61             return redirect('wagtailadmin_account')
  62     else:
  63         form = NotificationPreferencesForm(instance=UserProfile.get_for_user(request.user))
  64 
  65     # quick-and-dirty catch-all in case the form has been rendered with no
  66     # fields, as the user has no customisable permissions
  67     if not form.fields:
  68         return redirect('wagtailadmin_account')
  69 
  70     return render(request, 'wagtailadmin/account/notification_preferences.html', {
  71         'form': form,
  72     })
  73 
  74 
  75 @sensitive_post_parameters()
  76 @never_cache
  77 def login(request):
  78     if request.user.is_authenticated():
  79         return redirect('wagtailadmin_home')
  80     else:
  81         return auth_login(request,
  82             template_name='wagtailadmin/login.html',
  83             authentication_form=forms.LoginForm,
  84             extra_context={
  85                 'show_password_reset': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True),
  86             },
  87         )
  88 
  89 
  90 def logout(request):
  91     response = auth_logout(request, next_page = 'wagtailadmin_login')
  92 
  93     # By default, logging out will generate a fresh sessionid cookie. We want to use the
  94     # absence of sessionid as an indication that front-end pages are being viewed by a
  95     # non-logged-in user and are therefore cacheable, so we forcibly delete the cookie here.
  96     response.delete_cookie(settings.SESSION_COOKIE_NAME,
  97         domain=settings.SESSION_COOKIE_DOMAIN,
  98         path=settings.SESSION_COOKIE_PATH)
  99 
  100     # HACK: pretend that the session hasn't been modified, so that SessionMiddleware
  101     # won't override the above and write a new cookie.
  102     request.session.modified = False
  103 
  104     return response
  105
  [end of wagtail/wagtailadmin/views/account.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/wagtail/wagtailadmin/views/account.py b/wagtail/wagtailadmin/views/account.py
  --- a/wagtail/wagtailadmin/views/account.py
  +++ b/wagtail/wagtailadmin/views/account.py
  @@ -75,7 +75,7 @@
   @sensitive_post_parameters()
   @never_cache
   def login(request):
  -    if request.user.is_authenticated():
  +    if request.user.is_authenticated() and request.user.has_perm('wagtailadmin.access_admin'):
           return redirect('wagtailadmin_home')
       else:
           return auth_login(request,
  
verification_info: {"golden_diff": "diff --git a/wagtail/wagtailadmin/views/account.py b/wagtail/wagtailadmin/views/account.py\n--- a/wagtail/wagtailadmin/views/account.py\n+++ b/wagtail/wagtailadmin/views/account.py\n@@ -75,7 +75,7 @@\n @sensitive_post_parameters()\n @never_cache\n def login(request):\n-    if request.user.is_authenticated():\n+    if request.user.is_authenticated() and request.user.has_perm('wagtailadmin.access_admin'):\n         return redirect('wagtailadmin_home')\n     else:\n         return auth_login(request,\n", "issue": "Bug - Redirect loop\nThere seems to be a bug of redirection loop when a user (created without any admin/editor roles) attempts to log in. I was trying out the demo and apparently the admin interface does not cater for users without any roles.\n\nIt would be nice to know if there is a workaround this issue. Thanks!\n\n", "before_files": [{"content": "from django.conf import settings\nfrom django.shortcuts import render, redirect\nfrom django.contrib import messages\nfrom django.contrib.auth.forms import SetPasswordForm\nfrom django.contrib.auth.decorators import permission_required\nfrom django.contrib.auth.views import logout as auth_logout, login as auth_login\nfrom django.utils.translation import ugettext as _ \nfrom django.views.decorators.debug import sensitive_post_parameters\nfrom django.views.decorators.cache import never_cache\n\nfrom wagtail.wagtailadmin import forms\nfrom wagtail.wagtailusers.forms import NotificationPreferencesForm\nfrom wagtail.wagtailusers.models import UserProfile\nfrom wagtail.wagtailcore.models import UserPagePermissionsProxy\n\n\n@permission_required('wagtailadmin.access_admin')\ndef account(request):\n    user_perms = UserPagePermissionsProxy(request.user)\n    show_notification_preferences = user_perms.can_edit_pages() or user_perms.can_publish_pages()\n\n    return render(request, 'wagtailadmin/account/account.html', {\n        'show_change_password': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True) and request.user.has_usable_password(),\n        'show_notification_preferences': show_notification_preferences\n    })\n\n\n@permission_required('wagtailadmin.access_admin')\ndef change_password(request):\n    can_change_password = request.user.has_usable_password()\n\n    if can_change_password:\n        if request.POST:\n            form = SetPasswordForm(request.user, request.POST)\n\n            if form.is_valid():\n                form.save()\n\n                messages.success(request, _(\"Your password has been changed successfully!\"))\n                return redirect('wagtailadmin_account')\n        else:\n            form = SetPasswordForm(request.user)\n    else:\n        form = None\n\n    return render(request, 'wagtailadmin/account/change_password.html', {\n        'form': form,\n        'can_change_password': can_change_password,\n    })\n\n\n@permission_required('wagtailadmin.access_admin')\ndef notification_preferences(request):\n\n    if request.POST:\n        form = NotificationPreferencesForm(request.POST, instance=UserProfile.get_for_user(request.user))\n\n        if form.is_valid():\n            form.save()\n            messages.success(request, _(\"Your preferences have been updated successfully!\"))\n            return redirect('wagtailadmin_account')\n    else:\n        form = NotificationPreferencesForm(instance=UserProfile.get_for_user(request.user))\n\n    # quick-and-dirty catch-all in case the form has been rendered with no\n    # fields, as the user has no customisable permissions\n    if not form.fields:\n        return redirect('wagtailadmin_account')\n\n    return render(request, 'wagtailadmin/account/notification_preferences.html', {\n        'form': form,\n    })\n\n\n@sensitive_post_parameters()\n@never_cache\ndef login(request):\n    if request.user.is_authenticated():\n        return redirect('wagtailadmin_home')\n    else:\n        return auth_login(request,\n            template_name='wagtailadmin/login.html',\n            authentication_form=forms.LoginForm,\n            extra_context={\n                'show_password_reset': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True),\n            },\n        )\n\n\ndef logout(request):\n    response = auth_logout(request, next_page = 'wagtailadmin_login')\n\n    # By default, logging out will generate a fresh sessionid cookie. We want to use the\n    # absence of sessionid as an indication that front-end pages are being viewed by a\n    # non-logged-in user and are therefore cacheable, so we forcibly delete the cookie here.\n    response.delete_cookie(settings.SESSION_COOKIE_NAME,\n        domain=settings.SESSION_COOKIE_DOMAIN,\n        path=settings.SESSION_COOKIE_PATH)\n\n    # HACK: pretend that the session hasn't been modified, so that SessionMiddleware\n    # won't override the above and write a new cookie.\n    request.session.modified = False\n\n    return response\n", "path": "wagtail/wagtailadmin/views/account.py"}]}