Skip to content

Commit fd1eb1b

Browse files
authored
Merge pull request #294 from OpenSPP/fix/1124-registry-search-create-buttons
fix(registry_search): gate New Individual/Group buttons on registry create-permission roles (#1124)
2 parents 8e1ee43 + f714490 commit fd1eb1b

8 files changed

Lines changed: 97 additions & 5 deletions

File tree

spp_registry_search/README.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ Dependencies
124124
Changelog
125125
=========
126126

127+
19.0.2.1.1
128+
~~~~~~~~~~
129+
130+
- fix(security): gate the Registry Search "New Individual/Group" buttons
131+
on the registry create-permission roles instead of generic
132+
``res.partner`` create access, so roles without registrant-create
133+
rights (e.g. validators) can no longer initiate creation (#1124)
134+
127135
19.0.2.0.0
128136
~~~~~~~~~~
129137

spp_registry_search/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
"name": "OpenSPP Registry Search Portal",
44
"category": "OpenSPP/Registry",
5-
"version": "19.0.2.1.0",
5+
"version": "19.0.2.1.1",
66
"sequence": 1,
77
"author": "OpenSPP.org",
88
"website": "https://github.com/OpenSPP/OpenSPP2",

spp_registry_search/models/registry_view_history.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,33 @@ def check_registrant_edit_permission(self):
210210
continue
211211
return False
212212

213+
@api.model
214+
def check_registrant_create_permission(self):
215+
"""Check if current user can create registrants from the UI (OP#1124).
216+
217+
Generic ``res.partner`` create access is too broad — base Odoo grants it
218+
to most internal users — so it lets unintended roles (e.g. validators)
219+
initiate registrant creation from Registry Search. Only the same
220+
privileged registry roles allowed to edit may create.
221+
222+
Returns:
223+
bool: True if user can create registrants in the UI
224+
"""
225+
create_groups = [
226+
"base.group_system",
227+
"spp_security.group_spp_admin",
228+
"spp_registry.group_registry_manager",
229+
"spp_registry.group_registry_officer",
230+
]
231+
for group in create_groups:
232+
try:
233+
if self.env.user.has_group(group):
234+
return True
235+
except ValueError:
236+
# Group doesn't exist (module not installed)
237+
continue
238+
return False
239+
213240
@api.model
214241
def check_registrant_archive_permission(self):
215242
"""Check if current user can archive/unarchive registrants in the UI.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 19.0.2.1.1
2+
3+
- fix(security): gate the Registry Search "New Individual/Group" buttons on the registry create-permission roles instead of generic `res.partner` create access, so roles without registrant-create rights (e.g. validators) can no longer initiate creation (#1124)
4+
15
### 19.0.2.0.0
26

37
- Initial migration to OpenSPP2

spp_registry_search/static/description/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,15 @@ <h2><a class="toc-backref" href="#toc-entry-1">Changelog</a></h2>
497497
</div>
498498
</div>
499499
<div class="section" id="section-1">
500+
<h1>19.0.2.1.1</h1>
501+
<ul class="simple">
502+
<li>fix(security): gate the Registry Search “New Individual/Group” buttons
503+
on the registry create-permission roles instead of generic
504+
<tt class="docutils literal">res.partner</tt> create access, so roles without registrant-create
505+
rights (e.g. validators) can no longer initiate creation (#1124)</li>
506+
</ul>
507+
</div>
508+
<div class="section" id="section-2">
500509
<h1>19.0.2.0.0</h1>
501510
<ul class="simple">
502511
<li>Initial migration to OpenSPP2</li>

spp_registry_search/static/src/js/registry_search_portal.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ export class RegistrySearchPortal extends Component {
6060
onWillStart(async () => {
6161
try {
6262
const [canCreate, canEdit, recentlyViewed, config] = await Promise.all([
63-
this.orm.call("res.partner", "check_access_rights", [
64-
"create",
65-
false,
66-
]),
63+
// OP#1124: gate on the registry create-permission groups, not
64+
// generic res.partner create access (which base Odoo grants
65+
// broadly, letting validators/viewers initiate creation).
66+
this.orm.call(
67+
"spp.registry.view.history",
68+
"check_registrant_create_permission",
69+
[]
70+
),
6771
this.orm.call(
6872
"spp.registry.view.history",
6973
"check_registrant_edit_permission",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.
2+
from . import test_registrant_create_permission
23
from . import test_registry_view_history
34
from . import test_registry_view_history_security
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.
2+
"""OP#1124: Registry-search create buttons must be gated on the registry
3+
create-permission roles, not generic res.partner create access."""
4+
5+
from odoo.tests import TransactionCase, tagged
6+
7+
8+
@tagged("post_install", "-at_install")
9+
class TestRegistrantCreatePermission(TransactionCase):
10+
@classmethod
11+
def setUpClass(cls):
12+
super().setUpClass()
13+
cls.ViewHistory = cls.env["spp.registry.view.history"]
14+
15+
def _make_user(self, login, group_xmlids):
16+
groups = []
17+
for xmlid in group_xmlids:
18+
grp = self.env.ref(xmlid, raise_if_not_found=False)
19+
if grp:
20+
groups.append(grp.id)
21+
return self.env["res.users"].create({"name": login, "login": login, "group_ids": [(6, 0, groups)]})
22+
23+
def test_registry_officer_can_create(self):
24+
user = self._make_user("t_1124_officer", ["base.group_user", "spp_registry.group_registry_officer"])
25+
self.assertTrue(self.ViewHistory.with_user(user).check_registrant_create_permission())
26+
27+
def test_registry_manager_can_create(self):
28+
user = self._make_user("t_1124_manager", ["base.group_user", "spp_registry.group_registry_manager"])
29+
self.assertTrue(self.ViewHistory.with_user(user).check_registrant_create_permission())
30+
31+
def test_partner_creator_without_registry_role_cannot_create(self):
32+
"""A user with generic res.partner create access but NO registry role —
33+
like the validator in OP#1124 — must be denied. This is the crux: the
34+
old check keyed off res.partner create (which such a user passes)."""
35+
user = self._make_user("t_1124_partmgr", ["base.group_user", "base.group_partner_manager"])
36+
# Sanity: the old, too-broad basis (res.partner create) WOULD allow this user.
37+
self.assertTrue(self.env["res.partner"].with_user(user).check_access_rights("create", raise_exception=False))
38+
# The new, correct gate denies it (not a registry create role).
39+
self.assertFalse(self.ViewHistory.with_user(user).check_registrant_create_permission())

0 commit comments

Comments
 (0)