diff --git a/accountsplus/admin.py b/accountsplus/admin.py
index ed0bb1f..df8f7db 100644
--- a/accountsplus/admin.py
+++ b/accountsplus/admin.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.core.exceptions
import django.shortcuts
import django.http
@@ -21,8 +19,8 @@
from django.conf import settings
from django.apps import apps
-import signals
-import models
+from accountsplus import signals
+from accountsplus import models
sensitive_post_parameters_m = django.utils.decorators.method_decorator(
@@ -185,10 +183,11 @@ def reset_passwords(self, request, queryset):
reset_passwords.short_description = 'Send password reset emails to selected Users'
def get_timezone(self, obj):
- return unicode(obj.timezone)
+ return str(obj.timezone)
def masquerade(self, obj):
- return 'sign in'.format(django.urls.reverse('masquerade', kwargs={'user_id': obj.id}))
+ return django.utils.html.mark_safe(
+ 'sign in'.format(django.urls.reverse('masquerade', kwargs={'user_id': obj.id})))
masquerade.short_description = 'Sign in'
masquerade.allow_tags = True
diff --git a/accountsplus/apps.py b/accountsplus/apps.py
index f8f6117..e073873 100644
--- a/accountsplus/apps.py
+++ b/accountsplus/apps.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
from django.apps import AppConfig
diff --git a/accountsplus/context_processors.py b/accountsplus/context_processors.py
index 6b8b519..033c3e8 100644
--- a/accountsplus/context_processors.py
+++ b/accountsplus/context_processors.py
@@ -1,8 +1,5 @@
-from __future__ import unicode_literals
-
-
def masquerade_info(request):
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
return {
'is_masquerading': request.session.get('is_masquerading', False),
}
diff --git a/accountsplus/forms.py b/accountsplus/forms.py
index 6c9fbbc..5007950 100644
--- a/accountsplus/forms.py
+++ b/accountsplus/forms.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.forms
from django.conf import settings
from django.apps import apps
diff --git a/accountsplus/middleware.py b/accountsplus/middleware.py
index 3caa62b..ef7ee60 100644
--- a/accountsplus/middleware.py
+++ b/accountsplus/middleware.py
@@ -1,11 +1,10 @@
-from __future__ import unicode_literals
import django.utils.timezone
from django.utils.deprecation import MiddlewareMixin
class TimezoneMiddleware(MiddlewareMixin):
def process_request(self, request):
- if request.user.is_authenticated() and request.user.timezone:
+ if request.user.is_authenticated and request.user.timezone:
django.utils.timezone.activate(request.user.timezone)
else:
django.utils.timezone.deactivate()
diff --git a/accountsplus/models.py b/accountsplus/models.py
index 2f6d487..97bdfbc 100644
--- a/accountsplus/models.py
+++ b/accountsplus/models.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import logging
from django.utils.translation import ugettext_lazy as _
@@ -176,4 +174,4 @@ def delete(self, using=None, keep_parents=False):
@property
def is_masquerading(self):
- return self.masquerading_user_id > 0
+ return self.masquerading_user_id is not None and self.masquerading_user_id > 0
diff --git a/accountsplus/signals.py b/accountsplus/signals.py
index b7bf566..5c7db9e 100644
--- a/accountsplus/signals.py
+++ b/accountsplus/signals.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.contrib.auth.signals
from django.dispatch import receiver, Signal
from django.conf import settings
diff --git a/accountsplus/templatetags/__init__.py b/accountsplus/templatetags/__init__.py
index baffc48..e69de29 100644
--- a/accountsplus/templatetags/__init__.py
+++ b/accountsplus/templatetags/__init__.py
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/accountsplus/tests/test_admin.py b/accountsplus/tests/test_admin.py
index edc1a87..4920b43 100644
--- a/accountsplus/tests/test_admin.py
+++ b/accountsplus/tests/test_admin.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.test
import django.contrib.admin
diff --git a/accountsplus/tests/test_models.py b/accountsplus/tests/test_models.py
index d9382c3..af1c58e 100644
--- a/accountsplus/tests/test_models.py
+++ b/accountsplus/tests/test_models.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.test
import django.core.mail
import django.db.models
diff --git a/accountsplus/tests/test_signals.py b/accountsplus/tests/test_signals.py
index e23eaf4..5e038fc 100644
--- a/accountsplus/tests/test_signals.py
+++ b/accountsplus/tests/test_signals.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.test
import django.test.utils
diff --git a/accountsplus/tests/test_urls.py b/accountsplus/tests/test_urls.py
index cc649bd..693824c 100644
--- a/accountsplus/tests/test_urls.py
+++ b/accountsplus/tests/test_urls.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.test
import django.shortcuts
import django.conf.urls
diff --git a/accountsplus/tests/test_views.py b/accountsplus/tests/test_views.py
index b12d2c6..8aa1e2a 100644
--- a/accountsplus/tests/test_views.py
+++ b/accountsplus/tests/test_views.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.test
import django.test.utils
import django.test.client
diff --git a/accountsplus/urls.py b/accountsplus/urls.py
index 56edc40..6cf66f1 100644
--- a/accountsplus/urls.py
+++ b/accountsplus/urls.py
@@ -1,30 +1,29 @@
-from __future__ import unicode_literals
-
import django.conf.urls
-from django.contrib.auth.urls import url
+import django.contrib.auth.urls
import django.contrib.auth.views
-import views
-import forms
+
+from accountsplus import views
+from accountsplus import forms
urlpatterns = [
- url(r'^logout/$', views.logout_then_login, name='logout'),
- url(r'^password_change/$', views.password_change, name='password_change'),
- url(r'^password_reset/$', views.password_reset, name='password_reset'),
- url(r'^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
- django.contrib.auth.views.password_reset_confirm, name='password_reset_confirm'),
+ django.conf.urls.url(r'^logout/$', views.logout_then_login, name='logout'),
+ django.conf.urls.url(r'^password_change/$', views.password_change, name='password_change'),
+ django.conf.urls.url(r'^password_reset/$', django.contrib.auth.views.PasswordResetView.as_view(), name='password_reset'),
+ django.conf.urls.url(r'^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
+ django.contrib.auth.views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
# override the admin password reset flow to use the normal site password
# reset flow
- url(r'^password_reset/$', views.password_reset, name='admin_password_reset'),
+ django.conf.urls.url(r'^password_reset/$', views.password_reset, name='admin_password_reset'),
- url(r'^login/$',
- django.contrib.auth.views.login,
+ django.conf.urls.url(r'^login/$',
+ django.contrib.auth.views.LoginView.as_view(),
kwargs={'authentication_form': forms.EmailBasedAuthenticationForm, 'redirect_authenticated_user': True},
name='login'),
- url(r'^', django.conf.urls.include(django.contrib.auth.urls)),
+ django.conf.urls.url(r'^', django.conf.urls.include(django.contrib.auth.urls)),
# masquerade views
- url(r'^admin/masquerade/end/$', views.end_masquerade, name='end_masquerade'),
- url(r'^admin/masquerade/(?P\d+)/$', views.masquerade, name='masquerade'),
+ django.conf.urls.url(r'^admin/masquerade/end/$', views.EndMasqueradeUserView.as_view(), name='end_masquerade'),
+ django.conf.urls.url(r'^admin/masquerade/(?P\d+)/$', views.MasqueradeUserView.as_view(), name='masquerade'),
]
diff --git a/accountsplus/views.py b/accountsplus/views.py
index 015afae..4941214 100644
--- a/accountsplus/views.py
+++ b/accountsplus/views.py
@@ -1,10 +1,10 @@
-from __future__ import unicode_literals
import logging
from django.utils.translation import ugettext as _
import django.views.decorators.cache
import django.views.decorators.csrf
import django.views.decorators.debug
+import django.views.generic
import django.contrib.auth.decorators
import django.contrib.auth.views
import django.contrib.auth.forms
@@ -14,20 +14,24 @@
import django.http
import django.template.response
import django.utils.module_loading
-import django.core.urlresolvers
-from django.conf import settings as app_settings
+import django.urls
+from django.conf import settings
+from django.apps import apps
from axes import utils
-import signals
-import forms
-import settings
+from accountsplus import signals
+from accountsplus import forms
+from accountsplus import settings as accounts_settings
logger = logging.getLogger(__name__)
+SESSION_IS_MASQUERADING = 'is_masquerading'
+SESSION_MASQUERADE_USER_ID = 'masquerade_user_id'
-def logout_then_login(request, login_url=None, extra_context=None):
+
+def logout_then_login(request, login_url=None):
"""
Logs out the user if they are logged in. Then redirects to the log-in page.
"""
@@ -35,89 +39,43 @@ def logout_then_login(request, login_url=None, extra_context=None):
if request.session.get('is_masquerading'):
return django.shortcuts.redirect('end_masquerade')
else:
- return django.contrib.auth.views.logout_then_login(request, login_url, extra_context)
+ return django.contrib.auth.views.logout_then_login(request, login_url)
-@django.views.decorators.cache.never_cache
-@django.contrib.auth.decorators.login_required
-def masquerade(request, user_id=None):
- User = django.contrib.auth.get_user_model()
+class MasqueradeUserView(django.views.generic.RedirectView):
- return_page = request.META.get('HTTP_REFERER') or 'admin:index'
- if not user_id:
- django.contrib.messages.error(request, 'Masquerade failed: no user specified')
- return django.shortcuts.redirect(return_page)
- if not request.user.has_perm(User.PERMISSION_MASQUERADE):
- django.contrib.messages.error(request, 'Masquerade failed: insufficient privileges')
- return django.shortcuts.redirect(return_page)
- if not (request.user.is_superuser or request.user.is_staff):
- django.contrib.messages.error(request, 'Masquerade failed: must be staff or superuser')
- return django.shortcuts.redirect(return_page)
-
- try:
- user = User.objects.get(pk=user_id)
- except User.DoesNotExist:
- logger.error('User {} ({}) masquerading failed for user {}'.format(request.user.email, request.user.id, user_id))
- django.contrib.messages.error(request, 'Masquerade failed: unknown user {}'.format(user_id))
- return django.shortcuts.redirect(return_page)
-
- if user.is_superuser:
- logger.warning(
- 'User {} ({}) cannot masquerade as superuser {} ({})'.format(request.user.email, request.user.id, user.email, user.id))
- django.contrib.messages.warning(request, 'Cannot masquerade as a superuser')
- return django.shortcuts.redirect(return_page)
-
- admin_user = request.user
- user.backend = request.session[django.contrib.auth.BACKEND_SESSION_KEY]
- # log the new user in
- signals.masquerade_start.send(sender=masquerade, request=request, user=admin_user, masquerade_as=user)
- # this is needed to track whether this login is for a masquerade
- setattr(user, 'is_masquerading', True)
- setattr(user, 'masquerading_user', admin_user)
- django.contrib.auth.login(request, user)
-
- request.session['is_masquerading'] = True
- request.session['masquerade_user_id'] = admin_user.id
- request.session['return_page'] = return_page
- request.session['masquerade_is_superuser'] = admin_user.is_superuser
-
- logger.info(
- 'User {} ({}) masquerading as {} ({})'.format(admin_user.email, admin_user.id, request.user.email, request.user.id))
- django.contrib.messages.success(request, 'Masquerading as user {0}'.format(user.email))
-
- return django.http.HttpResponseRedirect(app_settings.LOGIN_REDIRECT_URL)
-
-
-@django.views.decorators.cache.never_cache
-@django.contrib.auth.decorators.login_required
-def end_masquerade(request):
- User = django.contrib.auth.get_user_model()
- if 'is_masquerading' not in request.session:
- return django.shortcuts.redirect('admin:index')
+ def get(self, request, *args, **kwargs):
+ admin_user = request.user
- if 'masquerade_user_id' in request.session:
- try:
- masqueraded_user = request.user
- user = User.objects.get(
- pk=request.session['masquerade_user_id'])
- user.backend = request.session[
- django.contrib.auth.BACKEND_SESSION_KEY]
- # this is needed to track whether this login is for a masquerade
- django.contrib.auth.logout(request)
- signals.masquerade_end.send(
- sender=end_masquerade, request=request, user=user,
- masquerade_as=masqueraded_user)
- django.contrib.auth.login(request, user)
- logging.info('End masquerade user: {} ({}) by: {} ({})'.format(
- masqueraded_user.email, masqueraded_user.id,
- user.email, user.id))
- django.contrib.messages.success(request, 'Masquerade ended')
- except User.DoesNotExist as e:
- logging.critical(
- 'Masquerading user {} does not exist'.format(
- request.session['masquerade_user_id']))
-
- return django.shortcuts.redirect('admin:index')
+ if not request.user.is_superuser:
+ django.contrib.messages.error(request, 'Masquerade failed: superuser only can masquerade')
+ return super(MasqueradeUserView, self).get(request, *args, **kwargs)
+
+ User = apps.get_model(settings.AUTH_USER_MODEL)
+ user = User.objects.get(pk=kwargs['user_id'])
+ user.backend = request.session[django.contrib.auth.BACKEND_SESSION_KEY]
+ django.contrib.auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
+
+ request.session[SESSION_IS_MASQUERADING] = True
+ request.session[SESSION_MASQUERADE_USER_ID] = admin_user.id
+ return super(MasqueradeUserView, self).get(request, *args, **kwargs)
+
+ def get_redirect_url(self, *args, **kwargs):
+ return settings.LOGIN_REDIRECT_URL
+
+
+class EndMasqueradeUserView(django.views.generic.RedirectView):
+
+ def get_redirect_url(self, *args, **kwargs):
+ return django.urls.reverse_lazy('admin:index')
+
+ def get(self, request, *args, **kwargs):
+ User = apps.get_model(settings.AUTH_USER_MODEL)
+ user = User.objects.get(pk=request.session[SESSION_MASQUERADE_USER_ID])
+ user.backend = request.session[django.contrib.auth.BACKEND_SESSION_KEY]
+ django.contrib.auth.logout(request)
+ django.contrib.auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
+ return super(EndMasqueradeUserView, self).get(request, *args, **kwargs)
@django.views.decorators.debug.sensitive_post_parameters()
@@ -130,7 +88,7 @@ def password_change(request,
PasswordChangeForm,
current_app=None, extra_context=None):
if post_change_redirect is None:
- post_change_redirect = django.core.urlresolvers.reverse(
+ post_change_redirect = django.urls.reverse(
'password_change_done')
else:
post_change_redirect = django.shortcuts.resolve_url(
@@ -173,7 +131,7 @@ def password_reset(request,
extra_email_context=None):
User = django.contrib.auth.get_user_model()
- response = django.contrib.auth.views.password_reset(
+ response = django.contrib.auth.views.PasswordResetView(
request, template_name, email_template_name,
subject_template_name, password_reset_form, token_generator,
post_reset_redirect, from_email, extra_context,
@@ -190,7 +148,7 @@ def password_reset(request,
class GenericLockedView(django.views.generic.FormView):
- template_name = settings.LOCKOUT_TEMPLATE
+ template_name = accounts_settings.LOCKOUT_TEMPLATE
form_class = forms.CaptchaForm
urlPattern = ''
diff --git a/requirements.txt b/requirements.txt
index 2d1a8fc..0d75a9c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
setuptools
-Django==1.10.1
+Django==2.2.1
flake8
pep8
pyflakes
diff --git a/settings_test.py b/settings_test.py
index 23e747a..d1721e0 100644
--- a/settings_test.py
+++ b/settings_test.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
import os
diff --git a/urls.py b/urls.py
index b030bcb..22f88cc 100644
--- a/urls.py
+++ b/urls.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import django.conf.urls
import django.contrib.admin