pyramid: added checks for password change for authenticated users.
This commit is contained in:
parent
5bee7acb7a
commit
4845dc40af
3 changed files with 42 additions and 15 deletions
|
|
@ -18,11 +18,14 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import time
|
||||
import logging
|
||||
from pylons import tmpl_context as c
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
||||
from rhodecode.lib.utils2 import StrictAttributeDict
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.lib.utils2 import StrictAttributeDict, safe_int
|
||||
from rhodecode.model.db import User
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -43,6 +46,34 @@ class BaseAppView(object):
|
|||
self.session = request.session
|
||||
self._rhodecode_user = request.user # auth user
|
||||
self._rhodecode_db_user = self._rhodecode_user.get_instance()
|
||||
self._maybe_needs_password_change(
|
||||
request.matched_route.name, self._rhodecode_db_user)
|
||||
|
||||
def _maybe_needs_password_change(self, view_name, user_obj):
|
||||
log.debug('Checking if user %s needs password change on view %s',
|
||||
user_obj, view_name)
|
||||
skip_user_views = [
|
||||
'logout', 'login',
|
||||
'my_account_password', 'my_account_password_update'
|
||||
]
|
||||
|
||||
if not user_obj:
|
||||
return
|
||||
|
||||
if user_obj.username == User.DEFAULT_USER:
|
||||
return
|
||||
|
||||
now = time.time()
|
||||
should_change = user_obj.user_data.get('force_password_change')
|
||||
change_after = safe_int(should_change) or 0
|
||||
if should_change and now > change_after:
|
||||
log.debug('User %s requires password change', user_obj)
|
||||
h.flash('You are required to change your password', 'warning',
|
||||
ignore_duplicate=True)
|
||||
|
||||
if view_name not in skip_user_views:
|
||||
raise HTTPFound(
|
||||
self.request.route_path('my_account_password'))
|
||||
|
||||
def _get_local_tmpl_context(self):
|
||||
c = TemplateArgs()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import pytest
|
|||
|
||||
from rhodecode.apps.login.views import LoginView, CaptchaData
|
||||
from rhodecode.config.routing import ADMIN_PREFIX
|
||||
from rhodecode.lib.utils2 import AttributeDict
|
||||
from rhodecode.model.settings import SettingsModel
|
||||
from rhodecode.tests.utils import AssertResponse
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ class RhodeCodeSetting(object):
|
|||
model.create_or_update_setting(name=self.name, val=self.value)
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
model = SettingsModel()
|
||||
if self.old_setting:
|
||||
model.create_or_update_setting(
|
||||
|
|
@ -57,8 +58,12 @@ class TestRegisterCaptcha(object):
|
|||
('privkey', '', CaptchaData(True, 'privkey', '')),
|
||||
('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')),
|
||||
])
|
||||
def test_get_captcha_data(self, private_key, public_key, expected, db):
|
||||
login_view = LoginView(mock.Mock(), mock.Mock())
|
||||
def test_get_captcha_data(self, private_key, public_key, expected, db,
|
||||
request_stub, user_util):
|
||||
request_stub.user = user_util.create_user().AuthUser
|
||||
request_stub.matched_route = AttributeDict({'name': 'login'})
|
||||
login_view = LoginView(mock.Mock(), request_stub)
|
||||
|
||||
with RhodeCodeSetting('captcha_private_key', private_key):
|
||||
with RhodeCodeSetting('captcha_public_key', public_key):
|
||||
captcha = login_view._get_captcha_data()
|
||||
|
|
|
|||
|
|
@ -489,21 +489,12 @@ class BaseController(WSGIController):
|
|||
_route_name)
|
||||
)
|
||||
|
||||
# TODO: Maybe this should be move to pyramid to cover all views.
|
||||
# check user attributes for password change flag
|
||||
user_obj = auth_user.get_instance()
|
||||
if user_obj and user_obj.user_data.get('force_password_change'):
|
||||
h.flash('You are required to change your password', 'warning',
|
||||
ignore_duplicate=True)
|
||||
|
||||
skip_user_check_urls = [
|
||||
'error.document', 'login.logout', 'login.index',
|
||||
'admin/my_account.my_account_password',
|
||||
'admin/my_account.my_account_password_update'
|
||||
]
|
||||
if _route_name not in skip_user_check_urls:
|
||||
return self._dispatch_redirect(
|
||||
url('my_account_password'), environ, start_response)
|
||||
return self._dispatch_redirect(
|
||||
url('my_account_password'), environ, start_response)
|
||||
|
||||
return WSGIController.__call__(self, environ, start_response)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue