Show More
@@ -18,11 +18,14 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | import time | |
|
21 | 22 | import logging |
|
22 | 23 | from pylons import tmpl_context as c |
|
23 | 24 | from pyramid.httpexceptions import HTTPFound |
|
24 | 25 | |
|
25 |
from rhodecode.lib |
|
|
26 | from rhodecode.lib import helpers as h | |
|
27 | from rhodecode.lib.utils2 import StrictAttributeDict, safe_int | |
|
28 | from rhodecode.model.db import User | |
|
26 | 29 | |
|
27 | 30 | log = logging.getLogger(__name__) |
|
28 | 31 | |
@@ -43,6 +46,34 b' class BaseAppView(object):' | |||
|
43 | 46 | self.session = request.session |
|
44 | 47 | self._rhodecode_user = request.user # auth user |
|
45 | 48 | self._rhodecode_db_user = self._rhodecode_user.get_instance() |
|
49 | self._maybe_needs_password_change( | |
|
50 | request.matched_route.name, self._rhodecode_db_user) | |
|
51 | ||
|
52 | def _maybe_needs_password_change(self, view_name, user_obj): | |
|
53 | log.debug('Checking if user %s needs password change on view %s', | |
|
54 | user_obj, view_name) | |
|
55 | skip_user_views = [ | |
|
56 | 'logout', 'login', | |
|
57 | 'my_account_password', 'my_account_password_update' | |
|
58 | ] | |
|
59 | ||
|
60 | if not user_obj: | |
|
61 | return | |
|
62 | ||
|
63 | if user_obj.username == User.DEFAULT_USER: | |
|
64 | return | |
|
65 | ||
|
66 | now = time.time() | |
|
67 | should_change = user_obj.user_data.get('force_password_change') | |
|
68 | change_after = safe_int(should_change) or 0 | |
|
69 | if should_change and now > change_after: | |
|
70 | log.debug('User %s requires password change', user_obj) | |
|
71 | h.flash('You are required to change your password', 'warning', | |
|
72 | ignore_duplicate=True) | |
|
73 | ||
|
74 | if view_name not in skip_user_views: | |
|
75 | raise HTTPFound( | |
|
76 | self.request.route_path('my_account_password')) | |
|
46 | 77 | |
|
47 | 78 | def _get_local_tmpl_context(self): |
|
48 | 79 | c = TemplateArgs() |
@@ -24,6 +24,7 b' import pytest' | |||
|
24 | 24 | |
|
25 | 25 | from rhodecode.apps.login.views import LoginView, CaptchaData |
|
26 | 26 | from rhodecode.config.routing import ADMIN_PREFIX |
|
27 | from rhodecode.lib.utils2 import AttributeDict | |
|
27 | 28 | from rhodecode.model.settings import SettingsModel |
|
28 | 29 | from rhodecode.tests.utils import AssertResponse |
|
29 | 30 | |
@@ -40,7 +41,7 b' class RhodeCodeSetting(object):' | |||
|
40 | 41 | model.create_or_update_setting(name=self.name, val=self.value) |
|
41 | 42 | return self |
|
42 | 43 | |
|
43 |
def __exit__(self, type, val |
|
|
44 | def __exit__(self, exc_type, exc_val, exc_tb): | |
|
44 | 45 | model = SettingsModel() |
|
45 | 46 | if self.old_setting: |
|
46 | 47 | model.create_or_update_setting( |
@@ -57,8 +58,12 b' class TestRegisterCaptcha(object):' | |||
|
57 | 58 | ('privkey', '', CaptchaData(True, 'privkey', '')), |
|
58 | 59 | ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')), |
|
59 | 60 | ]) |
|
60 |
def test_get_captcha_data(self, private_key, public_key, expected, db |
|
|
61 | login_view = LoginView(mock.Mock(), mock.Mock()) | |
|
61 | def test_get_captcha_data(self, private_key, public_key, expected, db, | |
|
62 | request_stub, user_util): | |
|
63 | request_stub.user = user_util.create_user().AuthUser | |
|
64 | request_stub.matched_route = AttributeDict({'name': 'login'}) | |
|
65 | login_view = LoginView(mock.Mock(), request_stub) | |
|
66 | ||
|
62 | 67 | with RhodeCodeSetting('captcha_private_key', private_key): |
|
63 | 68 | with RhodeCodeSetting('captcha_public_key', public_key): |
|
64 | 69 | captcha = login_view._get_captcha_data() |
@@ -489,21 +489,12 b' class BaseController(WSGIController):' | |||
|
489 | 489 | _route_name) |
|
490 | 490 | ) |
|
491 | 491 | |
|
492 | # TODO: Maybe this should be move to pyramid to cover all views. | |
|
493 | # check user attributes for password change flag | |
|
494 | 492 | user_obj = auth_user.get_instance() |
|
495 | 493 | if user_obj and user_obj.user_data.get('force_password_change'): |
|
496 | 494 | h.flash('You are required to change your password', 'warning', |
|
497 | 495 | ignore_duplicate=True) |
|
498 | ||
|
499 | skip_user_check_urls = [ | |
|
500 | 'error.document', 'login.logout', 'login.index', | |
|
501 | 'admin/my_account.my_account_password', | |
|
502 | 'admin/my_account.my_account_password_update' | |
|
503 | ] | |
|
504 | if _route_name not in skip_user_check_urls: | |
|
505 | return self._dispatch_redirect( | |
|
506 | url('my_account_password'), environ, start_response) | |
|
496 | return self._dispatch_redirect( | |
|
497 | url('my_account_password'), environ, start_response) | |
|
507 | 498 | |
|
508 | 499 | return WSGIController.__call__(self, environ, start_response) |
|
509 | 500 |
General Comments 0
You need to be logged in to leave comments.
Login now