Skip to content

Commit

Permalink
Merge PR #500 into 15.0
Browse files Browse the repository at this point in the history
Signed-off-by thomaspaulb
  • Loading branch information
OCA-git-bot committed Sep 23, 2023
2 parents 7a78fa5 + 367a85c commit 05b78fb
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 9 deletions.
2 changes: 1 addition & 1 deletion password_security/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"name": "Password Security",
"summary": "Allow admin to set password security requirements.",
"version": "15.0.1.1.4",
"version": "15.0.1.2.0",
"author": "LasLabs, "
"Onestein, "
"Kaushal Prajapati, "
Expand Down
17 changes: 17 additions & 0 deletions password_security/migrations/15.0.1.2.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2023 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)

import logging

from odoo import SUPERUSER_ID, api

_logger = logging.getLogger(__name__)


def migrate(cr, version):
if not version:
return
env = api.Environment(cr, SUPERUSER_ID, {})
companies = env["res.company"].with_context(active_test=False).search([])
_logger.info("Enable the password policy on %s companies", len(companies))
companies.write({"password_policy_enabled": True})
1 change: 1 addition & 0 deletions password_security/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class ResCompany(models.Model):
_inherit = "res.company"

password_policy_enabled = fields.Boolean(default=False)
password_expiration = fields.Integer(
"Days",
default=60,
Expand Down
3 changes: 3 additions & 0 deletions password_security/models/res_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

password_policy_enabled = fields.Boolean(
related="company_id.password_policy_enabled", readonly=False
)
password_expiration = fields.Integer(
related="company_id.password_expiration", readonly=False
)
Expand Down
14 changes: 12 additions & 2 deletions password_security/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def write(self, vals):
def get_password_policy(self):
data = super(ResUsers, self).get_password_policy()
company_id = self.env.user.company_id
if not company_id.password_policy_enabled:
return data
data.update(
{
"password_lower": company_id.password_lower,
Expand All @@ -69,7 +71,8 @@ def get_password_policy(self):

def _check_password_policy(self, passwords):
result = super(ResUsers, self)._check_password_policy(passwords)

if not self.env.user.company_id.password_policy_enabled:
return result
for password in passwords:
if not password:
continue
Expand Down Expand Up @@ -115,6 +118,8 @@ def password_match_message(self):
return "\r".join(message)

def _check_password(self, password):
if not self.env.user.company_id.password_policy_enabled:
return True
self._check_password_rules(password)
self._check_password_history(password)
return True
Expand Down Expand Up @@ -143,6 +148,8 @@ def _check_password_rules(self, password):

def _password_has_expired(self):
self.ensure_one()
if not self.company_id.password_policy_enabled:
return False
if not self.password_write_date:
return True

Expand All @@ -165,6 +172,8 @@ def _validate_pass_reset(self):
:return: True on allowed reset
"""
for user in self:
if not user.company_id.password_policy_enabled:
continue
pass_min = user.company_id.password_minimum
if pass_min <= 0:
continue
Expand Down Expand Up @@ -204,7 +213,8 @@ def _check_password_history(self, password):
def _set_encrypted_password(self, uid, pw):
"""It saves password crypt history for history rules"""
res = super(ResUsers, self)._set_encrypted_password(uid, pw)

if not self.env.user.company_id.password_policy_enabled:
return res
self.write({"password_history_ids": [(0, 0, {"password_crypt": pw})]})
return res

Expand Down
1 change: 1 addition & 0 deletions password_security/tests/test_password_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_check_password_history(self):
user = self.env.ref("base.user_admin")
user.company_id.update(
{
"password_policy_enabled": True,
"password_estimate": 0,
"password_length": 0,
"password_lower": 0,
Expand Down
7 changes: 7 additions & 0 deletions password_security/tests/test_password_security_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def __init__(self):
class TestPasswordSecurityHome(TransactionCase):
def setUp(self):
super(TestPasswordSecurityHome, self).setUp()
self.main_comp = self.env.ref("base.main_company")
self.main_comp.password_policy_enabled = True
self.PasswordSecurityHome = main.PasswordSecurityHome
self.password_security_home = self.PasswordSecurityHome()
self.passwd = "I am a password!"
Expand Down Expand Up @@ -175,6 +177,11 @@ def test_web_auth_signup_invalid_render(self):

@mock.patch("odoo.http.WebRequest.validate_csrf", return_value=True)
class LoginCase(HttpCase):
def setUp(self):
super(LoginCase, self).setUp()
self.main_comp = self.env.ref("base.main_company")
self.main_comp.password_policy_enabled = True

def test_web_login_authenticate(self, *args):
"""It should allow authenticating by login"""
response = self.url_open(
Expand Down
5 changes: 3 additions & 2 deletions password_security/tests/test_res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).

from odoo.exceptions import UserError
from odoo.tests.common import SavepointCase
from odoo.tests.common import TransactionCase


class TestResUsers(SavepointCase):
class TestResUsers(TransactionCase):
@classmethod
def setUpClass(cls):
super(TestResUsers, cls).setUpClass()
Expand All @@ -17,6 +17,7 @@ def setUpClass(cls):
}
cls.password = "asdQWE123$%^"
cls.main_comp = cls.env.ref("base.main_company")
cls.main_comp.password_policy_enabled = True
cls.vals = {
"name": "User",
"login": cls.login,
Expand Down
1 change: 1 addition & 0 deletions password_security/tests/test_reset_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class TestPasswordSecurityReset(HttpCase):
def setUp(self):
super().setUp()
self.env.company.password_policy_enabled = True

# Create user with strong password: no error raised
new_test_user(self.env, "jackoneill", password="!asdQWE12345_3")
Expand Down
20 changes: 16 additions & 4 deletions password_security/views/res_config_settings_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,23 @@
</xpath>
<!-- Add our password policy fields -->
<xpath expr="//div[@id='access_rights']" position="before">
<div class="col-12 col-lg-6 o_setting_box" title="Password Policy">
<div class="o_setting_left_pane" />
<div
class="col-12 col-lg-6 o_setting_box"
id="password_policy"
title="Password Policy"
>
<div class="o_setting_left_pane">
<field name="password_policy_enabled" />
</div>
<div class="o_setting_right_pane">
<label string="Password Policy" for="password_expiration" />
<div class="content-group">
<label string="Password Policy" for="password_policy_enabled" />
<div class="text-muted">
Set password security requirements
</div>
<div
class="content-group"
attrs="{'invisible': [('password_policy_enabled','=', False)]}"
>
<div class="mt16">
<span>
Password expires in
Expand Down

0 comments on commit 05b78fb

Please sign in to comment.