##// END OF EJS Templates
pyramid: added checks for password change for authenticated users.
marcink -
r1539:7998d3c5 default
parent child Browse files
Show More
@@ -18,11 +18,14 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import time
21 import logging
22 import logging
22 from pylons import tmpl_context as c
23 from pylons import tmpl_context as c
23 from pyramid.httpexceptions import HTTPFound
24 from pyramid.httpexceptions import HTTPFound
24
25
25 from rhodecode.lib.utils2 import StrictAttributeDict
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 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
28
31
@@ -43,6 +46,34 b' class BaseAppView(object):'
43 self.session = request.session
46 self.session = request.session
44 self._rhodecode_user = request.user # auth user
47 self._rhodecode_user = request.user # auth user
45 self._rhodecode_db_user = self._rhodecode_user.get_instance()
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 def _get_local_tmpl_context(self):
78 def _get_local_tmpl_context(self):
48 c = TemplateArgs()
79 c = TemplateArgs()
@@ -24,6 +24,7 b' import pytest'
24
24
25 from rhodecode.apps.login.views import LoginView, CaptchaData
25 from rhodecode.apps.login.views import LoginView, CaptchaData
26 from rhodecode.config.routing import ADMIN_PREFIX
26 from rhodecode.config.routing import ADMIN_PREFIX
27 from rhodecode.lib.utils2 import AttributeDict
27 from rhodecode.model.settings import SettingsModel
28 from rhodecode.model.settings import SettingsModel
28 from rhodecode.tests.utils import AssertResponse
29 from rhodecode.tests.utils import AssertResponse
29
30
@@ -40,7 +41,7 b' class RhodeCodeSetting(object):'
40 model.create_or_update_setting(name=self.name, val=self.value)
41 model.create_or_update_setting(name=self.name, val=self.value)
41 return self
42 return self
42
43
43 def __exit__(self, type, value, traceback):
44 def __exit__(self, exc_type, exc_val, exc_tb):
44 model = SettingsModel()
45 model = SettingsModel()
45 if self.old_setting:
46 if self.old_setting:
46 model.create_or_update_setting(
47 model.create_or_update_setting(
@@ -57,8 +58,12 b' class TestRegisterCaptcha(object):'
57 ('privkey', '', CaptchaData(True, 'privkey', '')),
58 ('privkey', '', CaptchaData(True, 'privkey', '')),
58 ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')),
59 ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')),
59 ])
60 ])
60 def test_get_captcha_data(self, private_key, public_key, expected, db):
61 def test_get_captcha_data(self, private_key, public_key, expected, db,
61 login_view = LoginView(mock.Mock(), mock.Mock())
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 with RhodeCodeSetting('captcha_private_key', private_key):
67 with RhodeCodeSetting('captcha_private_key', private_key):
63 with RhodeCodeSetting('captcha_public_key', public_key):
68 with RhodeCodeSetting('captcha_public_key', public_key):
64 captcha = login_view._get_captcha_data()
69 captcha = login_view._get_captcha_data()
@@ -489,21 +489,12 b' class BaseController(WSGIController):'
489 _route_name)
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 user_obj = auth_user.get_instance()
492 user_obj = auth_user.get_instance()
495 if user_obj and user_obj.user_data.get('force_password_change'):
493 if user_obj and user_obj.user_data.get('force_password_change'):
496 h.flash('You are required to change your password', 'warning',
494 h.flash('You are required to change your password', 'warning',
497 ignore_duplicate=True)
495 ignore_duplicate=True)
498
496 return self._dispatch_redirect(
499 skip_user_check_urls = [
497 url('my_account_password'), environ, start_response)
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)
507
498
508 return WSGIController.__call__(self, environ, start_response)
499 return WSGIController.__call__(self, environ, start_response)
509
500
General Comments 0
You need to be logged in to leave comments. Login now