pyramid: added checks for password change for authenticated users.

This commit is contained in:
Marcin Kuzminski 2017-03-14 12:40:01 +01:00
parent 5bee7acb7a
commit 4845dc40af
3 changed files with 42 additions and 15 deletions

View file

@ -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()

View file

@ -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()

View file

@ -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)