diff --git a/seahub/auth/views.py b/seahub/auth/views.py index 79e432f8dc..16f29ffc87 100644 --- a/seahub/auth/views.py +++ b/seahub/auth/views.py @@ -23,6 +23,7 @@ from seahub.auth.forms import AuthenticationForm, CaptchaAuthenticationForm from seahub.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm from seahub.auth.tokens import default_token_generator from seahub.base.accounts import User +from seahub.options.models import UserOptions from seahub.utils import is_ldap_user from seahub.utils.http import is_safe_url from seahub.utils.ip import get_remote_ip @@ -134,6 +135,11 @@ def login(request, template_name='registration/login.html', # have captcha form = CaptchaAuthenticationForm(data=request.POST) if form.is_valid(): + if UserOptions.objects.passwd_change_required( + form.get_user().username): + redirect_to = reverse('auth_password_change') + request.session['force_passwd_change'] = True + # captcha & passwod is valid, log user in request.session['remember_me'] = remember_me return log_user_in(request, form.get_user(), redirect_to) @@ -143,6 +149,11 @@ def login(request, template_name='registration/login.html', else: form = authentication_form(data=request.POST) if form.is_valid(): + if UserOptions.objects.passwd_change_required( + form.get_user().username): + redirect_to = reverse('auth_password_change') + request.session['force_passwd_change'] = True + # password is valid, log user in request.session['remember_me'] = remember_me return log_user_in(request, form.get_user(), redirect_to) @@ -365,6 +376,12 @@ 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() + + if request.session.get('force_passwd_change', False): + del request.session['force_passwd_change'] + UserOptions.objects.unset_force_passwd_change( + request.user.username) + update_session_auth_hash(request, request.user) return HttpResponseRedirect(post_change_redirect) else: @@ -375,6 +392,7 @@ def password_change(request, template_name='registration/password_change_form.ht 'min_len': config.USER_PASSWORD_MIN_LENGTH, 'strong_pwd_required': config.USER_STRONG_PASSWORD_REQUIRED, 'level': config.USER_PASSWORD_STRENGTH_LEVEL, + 'force_passwd_change': request.session.get('force_passwd_change', False), }, context_instance=RequestContext(request)) def password_change_done(request, template_name='registration/password_change_done.html'): diff --git a/seahub/base/middleware.py b/seahub/base/middleware.py index 6d9e35b115..61ff887d31 100644 --- a/seahub/base/middleware.py +++ b/seahub/base/middleware.py @@ -1,4 +1,8 @@ +import re + from django.core.cache import cache +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect import seaserv @@ -12,6 +16,7 @@ try: from seahub.settings import MULTI_TENANCY except ImportError: MULTI_TENANCY = False +from seahub.settings import SITE_ROOT class BaseMiddleware(object): """ @@ -70,3 +75,21 @@ class InfobarMiddleware(object): def process_response(self, request, response): return response + + +class ForcePasswdChangeMiddleware(object): + def _request_in_black_list(self, request): + path = request.path + black_list = (r'^%s$' % SITE_ROOT, r'home/.+', r'repo/.+', + r'[f|d]/[a-f][0-9]{10}', r'group/\d+', r'groups/', + r'share/', r'profile/', r'notification/list/') + + for patt in black_list: + if re.search(patt, path) is not None: + return True + return False + + def process_request(self, request): + if request.session.get('force_passwd_change', False): + if self._request_in_black_list(request): + return HttpResponseRedirect(reverse('auth_password_change')) diff --git a/seahub/options/models.py b/seahub/options/models.py index 3ceabd1c4d..2bb27fda25 100644 --- a/seahub/options/models.py +++ b/seahub/options/models.py @@ -18,6 +18,9 @@ KEY_SUB_LIB = "sub_lib" VAL_SUB_LIB_ENABLED = "1" VAL_SUB_LIB_DISABLED = "0" +KEY_FORCE_PASSWD_CHANGE = "force_passwd_change" +VAL_FORCE_PASSWD_CHANGE = "1" + KEY_DEFAULT_REPO = "default_repo" class CryptoOptionNotSetError(Exception): @@ -43,6 +46,11 @@ class UserOptionsManager(models.Manager): return user_option + def unset_user_option(self, username, k): + """Remove user's option. + """ + super(UserOptionsManager, self).filter(email=username, option_key=k).delete() + def enable_server_crypto(self, username): """ @@ -185,7 +193,24 @@ class UserOptionsManager(models.Manager): return user_option.option_val except UserOptions.DoesNotExist: return None - + + def passwd_change_required(self, username): + """Check whether user need to change password. + """ + try: + r = super(UserOptionsManager, self).get( + email=username, option_key=KEY_FORCE_PASSWD_CHANGE) + return r.option_val == VAL_FORCE_PASSWD_CHANGE + except UserOptions.DoesNotExist: + return False + + def set_force_passwd_change(self, username): + return self.set_user_option(username, KEY_FORCE_PASSWD_CHANGE, + VAL_FORCE_PASSWD_CHANGE) + + def unset_force_passwd_change(self, username): + return self.unset_user_option(username, KEY_FORCE_PASSWD_CHANGE) + class UserOptions(models.Model): email = LowerCaseCharField(max_length=255, db_index=True) option_key = models.CharField(max_length=50) diff --git a/seahub/settings.py b/seahub/settings.py index 54291d4f06..14aa9510ce 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -117,7 +117,8 @@ MIDDLEWARE_CLASSES = ( 'seahub.auth.middleware.AuthenticationMiddleware', 'seahub.base.middleware.BaseMiddleware', 'seahub.base.middleware.InfobarMiddleware', - 'seahub.password_session.middleware.CheckPasswordHash' + 'seahub.password_session.middleware.CheckPasswordHash', + 'seahub.base.middleware.ForcePasswdChangeMiddleware', ) SITE_ROOT_URLCONF = 'seahub.urls' diff --git a/seahub/templates/registration/password_change_form.html b/seahub/templates/registration/password_change_form.html index 64825a0ea2..a23833055b 100644 --- a/seahub/templates/registration/password_change_form.html +++ b/seahub/templates/registration/password_change_form.html @@ -7,6 +7,10 @@ {% endblock %} {% block main_panel %} +{% if force_passwd_change %} +
{% trans "Please update your password before continue." %}
+{% endif %} +