mirror of
https://github.com/haiwen/seahub.git
synced 2025-04-28 03:10:45 +00:00
add password_session app
This commit is contained in:
parent
ebf1d7f8d0
commit
f1b352e9ac
@ -29,6 +29,8 @@ from seahub.utils.ip import get_remote_ip
|
||||
from seahub.settings import USER_PASSWORD_MIN_LENGTH, \
|
||||
USER_STRONG_PASSWORD_REQUIRED, USER_PASSWORD_STRENGTH_LEVEL
|
||||
|
||||
from seahub.password_session import update_session_auth_hash
|
||||
|
||||
# Get an instance of a logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -352,6 +354,7 @@ def password_change(request, template_name='registration/password_change_form.ht
|
||||
form = password_change_form(user=request.user, data=request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
update_session_auth_hash(request, request.user)
|
||||
return HttpResponseRedirect(post_change_redirect)
|
||||
else:
|
||||
form = password_change_form(user=request.user)
|
||||
|
3
seahub/password_session/__init__.py
Normal file
3
seahub/password_session/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
VERSION = '0.3.3'
|
||||
|
||||
from .handlers import update_session_auth_hash
|
31
seahub/password_session/handlers.py
Normal file
31
seahub/password_session/handlers.py
Normal file
@ -0,0 +1,31 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.signals import user_logged_in
|
||||
from django.dispatch import receiver
|
||||
from hashlib import md5
|
||||
|
||||
PASSWORD_HASH_KEY = getattr(settings, 'PASSWORD_SESSION_PASSWORD_HASH_KEY', 'password_session_password_hash_key')
|
||||
|
||||
|
||||
def get_password_hash(user):
|
||||
"""Returns a string of crypted password hash"""
|
||||
password = user.password or ''
|
||||
return md5(
|
||||
md5(password.encode()).hexdigest().encode() + settings.SECRET_KEY.encode()
|
||||
).hexdigest()
|
||||
|
||||
|
||||
def update_session_auth_hash(request, user):
|
||||
"""
|
||||
Updates a session hash to prevent logging out `user` from a current session.
|
||||
|
||||
If `request.user` is defined through ``AuthenticationMiddleware``
|
||||
then make sure that `user` the same as `request.user`.
|
||||
"""
|
||||
if not hasattr(request, 'user') or request.user == user:
|
||||
request.session[PASSWORD_HASH_KEY] = get_password_hash(user)
|
||||
|
||||
|
||||
@receiver(user_logged_in)
|
||||
def on_login(sender, user, request, **kwargs):
|
||||
"""Saves password hash in session"""
|
||||
update_session_auth_hash(request, user)
|
11
seahub/password_session/middleware.py
Normal file
11
seahub/password_session/middleware.py
Normal file
@ -0,0 +1,11 @@
|
||||
from django.contrib.auth import logout
|
||||
|
||||
from .handlers import get_password_hash, PASSWORD_HASH_KEY
|
||||
|
||||
|
||||
class CheckPasswordHash(object):
|
||||
"""Logout user if value of hash key in session is not equal to current password hash"""
|
||||
def process_view(self, request, *args, **kwargs):
|
||||
if getattr(request.user, 'is_authenticated') and request.user.is_authenticated():
|
||||
if request.session.get(PASSWORD_HASH_KEY) != get_password_hash(request.user):
|
||||
logout(request)
|
1
seahub/password_session/models.py
Normal file
1
seahub/password_session/models.py
Normal file
@ -0,0 +1 @@
|
||||
# This file needs for tests
|
1
seahub/password_session/tests/__init__.py
Normal file
1
seahub/password_session/tests/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .tests import *
|
16
seahub/password_session/tests/test_urls.py
Normal file
16
seahub/password_session/tests/test_urls.py
Normal file
@ -0,0 +1,16 @@
|
||||
try:
|
||||
from django.conf.urls import url, patterns, include
|
||||
except ImportError: # for Django 1.3 compatibility
|
||||
from django.conf.urls.defaults import url, patterns, include
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .test_views import change_password_view
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^password/change/', change_password_view),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
13
seahub/password_session/tests/test_views.py
Normal file
13
seahub/password_session/tests/test_views.py
Normal file
@ -0,0 +1,13 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponse
|
||||
|
||||
from password_session import update_session_auth_hash
|
||||
|
||||
|
||||
@login_required(login_url='/admin/')
|
||||
def change_password_view(request):
|
||||
user = request.user
|
||||
user.set_password(request.POST.get('password'))
|
||||
user.save()
|
||||
update_session_auth_hash(request, user)
|
||||
return HttpResponse("Hello, %s! Your password has been changed!" % user.username)
|
47
seahub/password_session/tests/tests.py
Normal file
47
seahub/password_session/tests/tests.py
Normal file
@ -0,0 +1,47 @@
|
||||
from django.test import TestCase, Client
|
||||
|
||||
try:
|
||||
from django.contrib.auth import get_user_model
|
||||
except ImportError: # for Django 1.3 compatibility
|
||||
from django.contrib.auth.models import User as OldUser
|
||||
get_user_model = lambda: OldUser
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class PasswordSessionTest(TestCase):
|
||||
def setUp(self):
|
||||
self.password = 'qwe123'
|
||||
self.user = User.objects.create_user(email='albert@tugushev.ru', username='albert', password=self.password)
|
||||
self.user.is_superuser = True
|
||||
self.user.is_staff = True
|
||||
self.user.save()
|
||||
|
||||
def tearDown(self):
|
||||
self.user.delete()
|
||||
|
||||
def test_invalidate_session_after_change_password(self):
|
||||
# Test clients
|
||||
client1 = Client()
|
||||
client2 = Client()
|
||||
|
||||
# Auth client1 through django.test.client.login
|
||||
self.assertTrue(client1.login(username=self.user.username, password=self.password))
|
||||
|
||||
# Auth client2 through admin view
|
||||
response = client2.post('/admin/', follow=True, data={'username': self.user.username,
|
||||
'password': self.password,
|
||||
'this_is_the_login_form': 1,
|
||||
'next': '/admin/'},)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotContains(response, 'this_is_the_login_form')
|
||||
|
||||
# Change password for client1
|
||||
response = client1.post('/password/change/', data={'password': '123qwe'})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, 'Hello')
|
||||
|
||||
# client2 should be logged out
|
||||
response = client2.get('/admin/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, 'this_is_the_login_form')
|
@ -117,6 +117,7 @@ MIDDLEWARE_CLASSES = (
|
||||
'seahub.auth.middleware.AuthenticationMiddleware',
|
||||
'seahub.base.middleware.BaseMiddleware',
|
||||
'seahub.base.middleware.InfobarMiddleware',
|
||||
'seahub.password_session.middleware.CheckPasswordHash'
|
||||
)
|
||||
|
||||
SITE_ROOT_URLCONF = 'seahub.urls'
|
||||
@ -205,6 +206,7 @@ INSTALLED_APPS = (
|
||||
'seahub.share',
|
||||
'seahub.help',
|
||||
'seahub.thumbnail',
|
||||
'seahub.password_session',
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user