Skip to content

Commit aff70d1

Browse files
committed
[MIG] password_security: Add flag to toggle password security policy
This is a forward-ported commit of #500. Some portions were modified to handle multi-company environments
1 parent 7e72e73 commit aff70d1

16 files changed

+112
-34
lines changed

password_security/README.rst

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Password Security
77
!! This file is generated by oca-gen-addon-readme !!
88
!! changes will be overwritten. !!
99
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10-
!! source digest: sha256:dc29155c73a519d3732e2806f60bd11ebb31cd8c181ebd5918e4bc68080d37aa
10+
!! source digest: sha256:5f0bed48b7eca2655dceb715c14f64fd6a2703a6447e4f8f0401072dc03c3933
1111
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1212
1313
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -59,18 +59,19 @@ any user in that company.
5959

6060
These are defined at the company level:
6161

62-
===================== ======= ===================================================
63-
Name Default Description
64-
===================== ======= ===================================================
65-
password_expiration 60 Days until passwords expire
66-
password_length 12 Minimum number of characters in password
67-
password_lower 0 Minimum number of lowercase letter in password
68-
password_upper 0 Minimum number of uppercase letters in password
69-
password_numeric 0 Minimum number of number in password
70-
password_special 0 Minimum number of unique special character in password
71-
password_history 30 Disallow reuse of this many previous passwords
72-
password_minimum 24 Amount of hours that must pass until another reset
73-
===================== ======= ===================================================
62+
========================= ======= ===================================================
63+
Name Default Description
64+
========================= ======= ===================================================
65+
password_policy_enabled False Enables password security requirements
66+
password_expiration 60 Days until passwords expire
67+
password_length 12 Minimum number of characters in password
68+
password_lower 0 Minimum number of lowercase letter in password
69+
password_upper 0 Minimum number of uppercase letters in password
70+
password_numeric 0 Minimum number of number in password
71+
password_special 0 Minimum number of unique special character in password
72+
password_history 30 Disallow reuse of this many previous passwords
73+
password_minimum 24 Amount of hours that must pass until another reset
74+
========================= ======= ===================================================
7475

7576
Usage
7677
=====
@@ -120,6 +121,9 @@ Contributors
120121
* `Onestein <https://www.onestein.nl>`_:
121122
* Andrea Stirpe <[email protected]>
122123

124+
* `twio.tech <https://www.twio.tech>`_:
125+
* Dawn Hwang <[email protected]>
126+
123127
Maintainers
124128
~~~~~~~~~~~
125129

password_security/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{
66
"name": "Password Security",
77
"summary": "Allow admin to set password security requirements.",
8-
"version": "16.0.1.0.0",
8+
"version": "16.0.1.1.0",
99
"author": "LasLabs, "
1010
"Onestein, "
1111
"Kaushal Prajapati, "
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)
2+
3+
import logging
4+
5+
from odoo import SUPERUSER_ID, api
6+
7+
_logger = logging.getLogger(__name__)
8+
9+
10+
def migrate(cr, version):
11+
if not version:
12+
return
13+
env = api.Environment(cr, SUPERUSER_ID, {})
14+
companies = env["res.company"].with_context(active_test=False).search([])
15+
_logger.info("Enable the password policy on %s companies", len(companies))
16+
_logger.info(companies.mapped("name"))
17+
companies.write({"password_policy_enabled": True})

password_security/models/res_company.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
class ResCompany(models.Model):
99
_inherit = "res.company"
1010

11+
password_policy_enabled = fields.Boolean(
12+
"Password Policy",
13+
default=False,
14+
help="Enable password security requirements",
15+
)
1116
password_expiration = fields.Integer(
1217
"Days",
1318
default=60,

password_security/models/res_config_settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
class ResConfigSettings(models.TransientModel):
77
_inherit = "res.config.settings"
88

9+
password_policy_enabled = fields.Boolean(
10+
related="company_id.password_policy_enabled", readonly=False
11+
)
912
password_expiration = fields.Integer(
1013
related="company_id.password_expiration", readonly=False
1114
)

password_security/models/res_users.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ def write(self, vals):
3636
def get_password_policy(self):
3737
data = super(ResUsers, self).get_password_policy()
3838
company_id = self.env.user.company_id
39+
40+
if not company_id.password_policy_enabled:
41+
return data
42+
3943
data.update(
4044
{
4145
"password_lower": company_id.password_lower,
@@ -49,10 +53,10 @@ def get_password_policy(self):
4953
def _check_password_policy(self, passwords):
5054
result = super(ResUsers, self)._check_password_policy(passwords)
5155

52-
for password in passwords:
56+
for user, password in zip(self, passwords):
5357
if not password:
5458
continue
55-
self._check_password(password)
59+
user._check_password(password)
5660

5761
return result
5862

@@ -92,6 +96,8 @@ def password_match_message(self):
9296
return "\r".join(message)
9397

9498
def _check_password(self, password):
99+
if not self.company_id.password_policy_enabled:
100+
return True
95101
self._check_password_rules(password)
96102
self._check_password_history(password)
97103
return True
@@ -118,6 +124,9 @@ def _check_password_rules(self, password):
118124

119125
def _password_has_expired(self):
120126
self.ensure_one()
127+
if not self.company_id.password_policy_enabled:
128+
return False
129+
121130
if not self.password_write_date:
122131
return True
123132

@@ -140,6 +149,9 @@ def _validate_pass_reset(self):
140149
:return: True on allowed reset
141150
"""
142151
for user in self:
152+
if not user.company_id.password_policy_enabled:
153+
continue
154+
143155
pass_min = user.company_id.password_minimum
144156
if pass_min <= 0:
145157
continue
@@ -180,6 +192,9 @@ def _set_encrypted_password(self, uid, pw):
180192
"""It saves password crypt history for history rules"""
181193
res = super(ResUsers, self)._set_encrypted_password(uid, pw)
182194

195+
if not self.browse(uid).company_id.password_policy_enabled:
196+
return res
197+
183198
self.env["res.users.pass.history"].create(
184199
{
185200
"user_id": uid,

password_security/readme/CONFIGURE.rst

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ any user in that company.
99

1010
These are defined at the company level:
1111

12-
===================== ======= ===================================================
13-
Name Default Description
14-
===================== ======= ===================================================
15-
password_expiration 60 Days until passwords expire
16-
password_length 12 Minimum number of characters in password
17-
password_lower 0 Minimum number of lowercase letter in password
18-
password_upper 0 Minimum number of uppercase letters in password
19-
password_numeric 0 Minimum number of number in password
20-
password_special 0 Minimum number of unique special character in password
21-
password_history 30 Disallow reuse of this many previous passwords
22-
password_minimum 24 Amount of hours that must pass until another reset
23-
===================== ======= ===================================================
12+
========================= ======= ===================================================
13+
Name Default Description
14+
========================= ======= ===================================================
15+
password_policy_enabled False Enables password security requirements
16+
password_expiration 60 Days until passwords expire
17+
password_length 12 Minimum number of characters in password
18+
password_lower 0 Minimum number of lowercase letter in password
19+
password_upper 0 Minimum number of uppercase letters in password
20+
password_numeric 0 Minimum number of number in password
21+
password_special 0 Minimum number of unique special character in password
22+
password_history 30 Disallow reuse of this many previous passwords
23+
password_minimum 24 Amount of hours that must pass until another reset
24+
========================= ======= ===================================================

password_security/readme/CONTRIBUTORS.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313

1414
* `Onestein <https://www.onestein.nl>`_:
1515
* Andrea Stirpe <[email protected]>
16+
17+
* `twio.tech <https://www.twio.tech>`_:
18+
* Dawn Hwang <[email protected]>

password_security/static/description/index.html

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ <h1 class="title">Password Security</h1>
367367
!! This file is generated by oca-gen-addon-readme !!
368368
!! changes will be overwritten. !!
369369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
370-
!! source digest: sha256:dc29155c73a519d3732e2806f60bd11ebb31cd8c181ebd5918e4bc68080d37aa
370+
!! source digest: sha256:5f0bed48b7eca2655dceb715c14f64fd6a2703a6447e4f8f0401072dc03c3933
371371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372372
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-auth/tree/16.0/password_security"><img alt="OCA/server-auth" src="https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-password_security"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-auth&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
373373
<p>This module allows admin to set company-level password security requirements
@@ -406,9 +406,9 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
406406
<p>These are defined at the company level:</p>
407407
<table border="1" class="docutils">
408408
<colgroup>
409-
<col width="26%" />
410-
<col width="9%" />
411-
<col width="66%" />
409+
<col width="29%" />
410+
<col width="8%" />
411+
<col width="63%" />
412412
</colgroup>
413413
<thead valign="bottom">
414414
<tr><th class="head">Name</th>
@@ -417,6 +417,10 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
417417
</tr>
418418
</thead>
419419
<tbody valign="top">
420+
<tr><td>password_policy_enabled</td>
421+
<td>False</td>
422+
<td>Enables password security requirements</td>
423+
</tr>
420424
<tr><td>password_expiration</td>
421425
<td>60</td>
422426
<td>Days until passwords expire</td>
@@ -511,6 +515,14 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
511515
</dd>
512516
</dl>
513517
</li>
518+
<li><dl class="first docutils">
519+
<dt><a class="reference external" href="https://www.twio.tech">twio.tech</a>:</dt>
520+
<dd><ul class="first last simple">
521+
<li>Dawn Hwang &lt;<a class="reference external" href="mailto:hwangh95&#64;gmail.com">hwangh95&#64;gmail.com</a>&gt;</li>
522+
</ul>
523+
</dd>
524+
</dl>
525+
</li>
514526
</ul>
515527
</div>
516528
<div class="section" id="maintainers">

password_security/tests/test_change_password.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def login(self, username, password):
1515
self.session = http.root.session_store.new()
1616
self.opener = Opener(self.env.cr)
1717
self.opener.cookies.set("session_id", self.session.sid, domain=HOST, path="/")
18+
self.env.company.password_policy_enabled = True
1819

1920
with mock.patch("odoo.http.db_filter") as db_filter:
2021
db_filter.side_effect = lambda dbs, host=None: [get_db_name()]

0 commit comments

Comments
 (0)