diff --git a/password_security/__manifest__.py b/password_security/__manifest__.py index f842b5d01..cf95f41db 100644 --- a/password_security/__manifest__.py +++ b/password_security/__manifest__.py @@ -4,8 +4,12 @@ 'name': 'Password Security', "summary": "Allow admin to set password security requirements.", - 'version': '11.0.1.0.0', - 'author': "LasLabs, Odoo Community Association (OCA), Kaushal Prajapati", + 'version': '11.0.1.0.1', + 'author': + "LasLabs, " + "Kaushal Prajapati, " + "Tecnativa, " + "Odoo Community Association (OCA)", 'category': 'Base', 'depends': [ 'auth_crypt', diff --git a/password_security/controllers/main.py b/password_security/controllers/main.py index 7f8d73a9d..c3a372477 100644 --- a/password_security/controllers/main.py +++ b/password_security/controllers/main.py @@ -35,22 +35,15 @@ def do_signup(self, qcontext): def web_login(self, *args, **kw): ensure_db() response = super(PasswordSecurityHome, self).web_login(*args, **kw) - if not request.httprequest.method == 'POST': + if not request.params.get("login_success"): return response - uid = request.session.authenticate( - request.session.db, - request.params['login'], - request.params['password'] - ) - if not uid: - return response - users_obj = request.env['res.users'].sudo() - user_id = users_obj.browse(request.uid) - if not user_id._password_has_expired(): + # Now, I'm an authenticated user + if not request.env.user._password_has_expired(): return response - user_id.action_expire_password() + # My password is expired, kick me out + request.env.user.action_expire_password() request.session.logout(keep_db=True) - redirect = user_id.partner_id.signup_url + redirect = request.env.user.partner_id.signup_url return http.redirect_with_hash(redirect) @http.route() diff --git a/password_security/tests/test_password_security_home.py b/password_security/tests/test_password_security_home.py index 3f5dc33e6..90634f82d 100644 --- a/password_security/tests/test_password_security_home.py +++ b/password_security/tests/test_password_security_home.py @@ -1,11 +1,12 @@ # Copyright 2016 LasLabs Inc. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). -import mock +from datetime import datetime, timedelta +from unittest import mock from contextlib import contextmanager -from odoo.tests.common import TransactionCase +from odoo.tests.common import HttpCase, TransactionCase from odoo.http import Response from ..controllers import main @@ -102,82 +103,6 @@ def test_web_login_super(self): *expect_list, **expect_dict ) - def test_web_login_no_post(self): - """ It should return immediate result of super when not POST """ - with self.mock_assets() as assets: - assets['request'].httprequest.method = 'GET' - assets['request'].session.authenticate.side_effect = \ - EndTestException - res = self.password_security_home.web_login() - self.assertEqual( - assets['web_login'](), res, - ) - - def test_web_login_authenticate(self): - """ It should attempt authentication to obtain uid """ - with self.mock_assets() as assets: - assets['request'].httprequest.method = 'POST' - authenticate = assets['request'].session.authenticate - request = assets['request'] - authenticate.side_effect = EndTestException - with self.assertRaises(EndTestException): - self.password_security_home.web_login() - authenticate.assert_called_once_with( - request.session.db, - request.params['login'], - request.params['password'], - ) - - def test_web_login_authenticate_fail(self): - """ It should return super result if failed auth """ - with self.mock_assets() as assets: - authenticate = assets['request'].session.authenticate - request = assets['request'] - request.httprequest.method = 'POST' - request.env['res.users'].sudo.side_effect = EndTestException - authenticate.return_value = False - res = self.password_security_home.web_login() - self.assertEqual( - assets['web_login'](), res, - ) - - def test_web_login_get_user(self): - """ It should get the proper user as sudo """ - with self.mock_assets() as assets: - request = assets['request'] - request.httprequest.method = 'POST' - sudo = request.env['res.users'].sudo() - sudo.browse.side_effect = EndTestException - with self.assertRaises(EndTestException): - self.password_security_home.web_login() - sudo.browse.assert_called_once_with( - request.uid - ) - - def test_web_login_valid_pass(self): - """ It should return parent result if pass isn't expired """ - with self.mock_assets() as assets: - request = assets['request'] - request.httprequest.method = 'POST' - user = request.env['res.users'].sudo().browse() - user.action_expire_password.side_effect = EndTestException - user._password_has_expired.return_value = False - res = self.password_security_home.web_login() - self.assertEqual( - assets['web_login'](), res, - ) - - def test_web_login_expire_pass(self): - """ It should expire password if necessary """ - with self.mock_assets() as assets: - request = assets['request'] - request.httprequest.method = 'POST' - user = request.env['res.users'].sudo().browse() - user.action_expire_password.side_effect = EndTestException - user._password_has_expired.return_value = True - with self.assertRaises(EndTestException): - self.password_security_home.web_login() - def test_web_login_log_out_if_expired(self): """It should log out user if password expired""" with self.mock_assets() as assets: @@ -278,3 +203,44 @@ def test_web_auth_reset_password_success(self): self.assertEqual( assets['web_auth_reset_password'](), res, ) + + +@mock.patch("odoo.http.WebRequest.validate_csrf", return_value=True) +class LoginCase(HttpCase): + def test_web_login_authenticate(self, *args): + """It should allow authenticating by login""" + response = self.url_open( + "/web/login", + {"login": "admin", "password": "admin"}, + ) + self.assertIn( + "window.location = '/web'", + response.text, + ) + + def test_web_login_authenticate_fail(self, *args): + """It should fail auth""" + response = self.url_open( + "/web/login", + {"login": "admin", "password": "noadmin"}, + ) + self.assertIn( + "Wrong login/password", + response.text, + ) + + def test_web_login_expire_pass(self, *args): + """It should expire password if necessary""" + two_days_ago = datetime.now() - timedelta(days=2) + with self.cursor() as cr: + env = self.env(cr) + env.user.password_write_date = two_days_ago + env.user.company_id.password_expiration = 1 + response = self.url_open( + "/web/login", + {"login": "admin", "password": "admin"}, + ) + self.assertIn( + "/web/reset_password", + response.text, + )