Skip to content

Commit 442b0ac

Browse files
committed
merge: resolve conflicts with 19.0 — bump spp_change_request_v2 to 19.0.2.0.6
Stacked HISTORY entry (#920 round-2 view fix) on top of main's 19.0.2.0.5 security fix (OP#989). README.rst + static/description/index.html updated to match HISTORY.md ordering.
2 parents 5881862 + b106560 commit 442b0ac

37 files changed

Lines changed: 1591 additions & 272 deletions

spp_area/README.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ Dependencies
140140
Changelog
141141
=========
142142

143+
19.0.2.0.1
144+
~~~~~~~~~~
145+
146+
- fix(security): add a global ``ir.rule`` on ``res.partner`` that
147+
filters registrants by ``area_id`` for users with ``center_area_ids``
148+
set (OP#989). Replaces the limited ``search_read`` /
149+
``web_search_read`` override in ``models/registrant.py`` which missed
150+
``name_search`` (Many2one dropdowns), ``search_count``,
151+
``read_group``, and related-field traversal. The rule's conditional
152+
domain is a no-op for users without center areas (global roles).
153+
143154
19.0.2.0.0
144155
~~~~~~~~~~
145156

spp_area/__manifest__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"name": "OpenSPP Area Management",
77
"summary": "Establishes direct associations between OpenSPP registrants, beneficiary groups, and their corresponding geographical administrative areas. It validates registrant-area linkages against official area types, ensuring data integrity and enabling targeted program delivery and analysis.",
88
"category": "OpenSPP/Core",
9-
"version": "19.0.2.0.0",
9+
"version": "19.0.2.0.1",
1010
"sequence": 1,
1111
"author": "OpenSPP.org",
1212
"website": "https://github.com/OpenSPP/OpenSPP2",
@@ -33,6 +33,7 @@
3333
"security/privileges.xml",
3434
"security/groups.xml",
3535
"security/ir.model.access.csv",
36+
"security/rules.xml",
3637
"wizard/area_import_language_wizard_views.xml",
3738
"views/area_base.xml",
3839
"views/area_tag.xml",

spp_area/readme/HISTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 19.0.2.0.1
2+
3+
- fix(security): add a global `ir.rule` on `res.partner` that filters registrants by `area_id` for users with `center_area_ids` set (OP#989). Replaces the limited `search_read` / `web_search_read` override in `models/registrant.py` which missed `name_search` (Many2one dropdowns), `search_count`, `read_group`, and related-field traversal. The rule's conditional domain is a no-op for users without center areas (global roles).
4+
15
### 19.0.2.0.0
26

37
- Initial migration to OpenSPP2

spp_area/security/rules.xml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<!--
3+
Part of OpenSPP. See LICENSE file for full copyright and licensing details.
4+
5+
Area-based row-level filtering for registrants (OP#989).
6+
7+
Replaces / strengthens the `_prepare_domain` override in models/registrant.py
8+
which only catches `search_read` / `web_search_read`. An ir.rule applies to
9+
every ORM read path automatically: `search`, `search_count`, `read_group`,
10+
`name_search` (Many2one dropdowns), `read`, and related-field traversal.
11+
12+
The rule is scoped to `is_registrant = True` only — non-registrant contacts
13+
(users' own partners, admins, companies, system bots, mail followers) must
14+
remain readable, otherwise every record using `message_partner_ids` /
15+
`message_follower_ids` blows up for local users with `center_area_ids`.
16+
17+
The conditional domain makes the rule a no-op for users without
18+
`center_area_ids` (global roles).
19+
-->
20+
<odoo noupdate="1">
21+
<record id="rule_res_partner_area_filter" model="ir.rule">
22+
<field name="name">Registrants: visible only within user's center areas</field>
23+
<field name="model_id" ref="base.model_res_partner" />
24+
<field
25+
name="domain_force"
26+
>['|', ('is_registrant', '=', False), ('area_id', 'child_of', user.center_area_ids.ids)] if user.center_area_ids else []</field>
27+
<field name="global" eval="True" />
28+
<field name="perm_read" eval="True" />
29+
<field name="perm_write" eval="True" />
30+
<field name="perm_create" eval="True" />
31+
<field name="perm_unlink" eval="True" />
32+
</record>
33+
</odoo>

spp_area/static/description/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,18 @@ <h2><a class="toc-backref" href="#toc-entry-1">Changelog</a></h2>
537537
</div>
538538
</div>
539539
<div class="section" id="section-1">
540+
<h1>19.0.2.0.1</h1>
541+
<ul class="simple">
542+
<li>fix(security): add a global <tt class="docutils literal">ir.rule</tt> on <tt class="docutils literal">res.partner</tt> that
543+
filters registrants by <tt class="docutils literal">area_id</tt> for users with <tt class="docutils literal">center_area_ids</tt>
544+
set (OP#989). Replaces the limited <tt class="docutils literal">search_read</tt> /
545+
<tt class="docutils literal">web_search_read</tt> override in <tt class="docutils literal">models/registrant.py</tt> which missed
546+
<tt class="docutils literal">name_search</tt> (Many2one dropdowns), <tt class="docutils literal">search_count</tt>,
547+
<tt class="docutils literal">read_group</tt>, and related-field traversal. The rule’s conditional
548+
domain is a no-op for users without center areas (global roles).</li>
549+
</ul>
550+
</div>
551+
<div class="section" id="section-2">
540552
<h1>19.0.2.0.0</h1>
541553
<ul class="simple">
542554
<li>Initial migration to OpenSPP2</li>

spp_change_request_v2/README.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ Before declaring a new CR type complete:
853853
Changelog
854854
=========
855855

856-
19.0.2.0.4
856+
19.0.2.0.6
857857
~~~~~~~~~~
858858

859859
- fix(views): route post-submit CRs (pending / approved / applied /
@@ -867,6 +867,18 @@ Changelog
867867
and wires ``action="action_open_stage_form" type="object"`` on the CR
868868
list so row-click goes through the stage router.
869869

870+
19.0.2.0.5
871+
~~~~~~~~~~
872+
873+
- fix(security): add a global ``ir.rule`` on ``spp.change.request`` that
874+
filters by ``registrant_id.area_id`` against the user's
875+
``center_area_ids`` (OP#989 round-2). The earlier ``_prepare_domain``
876+
override only caught ``search_read`` / ``web_search_read`` and missed
877+
the registrant Many2one picker (which uses ``name_search`` →
878+
``_search``), so users could still select out-of-area registrants. The
879+
conditional domain is a no-op for users with no center areas (global
880+
roles).
881+
870882
19.0.2.0.3
871883
~~~~~~~~~~
872884

spp_change_request_v2/__manifest__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "OpenSPP Change Request V2",
3-
"version": "19.0.2.0.4",
3+
"version": "19.0.2.0.6",
44
"sequence": 50,
55
"category": "OpenSPP",
66
"summary": "Configuration-driven change request system with UX improvements, conflict detection and duplicate prevention",
@@ -13,6 +13,7 @@
1313
"mail",
1414
"spp_base_common",
1515
"spp_registry",
16+
"spp_area",
1617
"spp_security",
1718
"spp_approval",
1819
"spp_event_data",
@@ -24,6 +25,7 @@
2425
"security/privileges.xml",
2526
"security/groups.xml",
2627
"security/rules.xml",
28+
"security/area_filter_rules.xml",
2729
"security/ir.model.access.csv",
2830
# Views (loaded before data that references them)
2931
"views/dms_file_views.xml",

spp_change_request_v2/readme/HISTORY.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
### 19.0.2.0.4
1+
### 19.0.2.0.6
22

33
- fix(views): route post-submit CRs (pending / approved / applied / rejected) through the stage review form when opened from the list, matching the Edit Details → Upload Documents → Review & Submit breadcrumb workflow used for fresh CRs (#920 round-2). Demo-generated CRs in "Applied" state previously landed on the legacy main form view from the list — now they open in `spp_change_request_review_form` like manually-created CRs. Adds the missing `_action_open_review_form` / `_action_open_documents_form` helpers and wires `action="action_open_stage_form" type="object"` on the CR list so row-click goes through the stage router.
44

5+
### 19.0.2.0.5
6+
7+
- fix(security): add a global `ir.rule` on `spp.change.request` that filters by `registrant_id.area_id` against the user's `center_area_ids` (OP#989 round-2). The earlier `_prepare_domain` override only caught `search_read` / `web_search_read` and missed the registrant Many2one picker (which uses `name_search``_search`), so users could still select out-of-area registrants. The conditional domain is a no-op for users with no center areas (global roles).
8+
59
### 19.0.2.0.3
610

711
- fix: add HTML escaping to all computed Html fields with `sanitize=False` to prevent stored XSS (#50)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<!--
3+
Part of OpenSPP. See LICENSE file for full copyright and licensing details.
4+
5+
Area-based row-level filtering for change requests (OP#989).
6+
7+
QA round 1 surfaced that the original `_prepare_domain` override on
8+
`spp.change.request` only caught `search_read` / `web_search_read`. The
9+
registrant picker on the CR form (a Many2one widget) calls `name_search` ->
10+
`_search` and bypasses the override. An ir.rule applies to every ORM read
11+
path automatically, including `name_search`, `search_count`, `read_group`,
12+
and related-field traversal.
13+
14+
Mirrors the conditional domain pattern from `spp_area/security/rules.xml`
15+
so users without `center_area_ids` (global roles) are unaffected. The
16+
module now depends on `spp_area` directly so `user.center_area_ids`
17+
can be referenced without defensive guards.
18+
-->
19+
<odoo noupdate="1">
20+
<record id="rule_spp_change_request_area_filter" model="ir.rule">
21+
<field
22+
name="name"
23+
>Change Request: visible only within user's center areas</field>
24+
<field name="model_id" ref="model_spp_change_request" />
25+
<field
26+
name="domain_force"
27+
>[('registrant_id.area_id', 'child_of', user.center_area_ids.ids)] if user.center_area_ids else []</field>
28+
<field name="global" eval="True" />
29+
<field name="perm_read" eval="True" />
30+
<field name="perm_write" eval="True" />
31+
<field name="perm_create" eval="True" />
32+
<field name="perm_unlink" eval="True" />
33+
</record>
34+
</odoo>

spp_change_request_v2/static/description/index.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ <h2>Changelog</h2>
13391339
</div>
13401340
</div>
13411341
<div class="section" id="section-1">
1342-
<h1>19.0.2.0.4</h1>
1342+
<h1>19.0.2.0.6</h1>
13431343
<ul class="simple">
13441344
<li>fix(views): route post-submit CRs (pending / approved / applied /
13451345
rejected) through the stage review form when opened from the list,
@@ -1353,6 +1353,19 @@ <h1>19.0.2.0.4</h1>
13531353
list so row-click goes through the stage router.</li>
13541354
</ul>
13551355
</div>
1356+
<div class="section" id="section-1-5">
1357+
<h1>19.0.2.0.5</h1>
1358+
<ul class="simple">
1359+
<li>fix(security): add a global <tt class="docutils literal">ir.rule</tt> on <tt class="docutils literal">spp.change.request</tt> that
1360+
filters by <tt class="docutils literal">registrant_id.area_id</tt> against the user’s
1361+
<tt class="docutils literal">center_area_ids</tt> (OP#989 round-2). The earlier <tt class="docutils literal">_prepare_domain</tt>
1362+
override only caught <tt class="docutils literal">search_read</tt> / <tt class="docutils literal">web_search_read</tt> and missed
1363+
the registrant Many2one picker (which uses <tt class="docutils literal">name_search</tt>
1364+
<tt class="docutils literal">_search</tt>), so users could still select out-of-area registrants. The
1365+
conditional domain is a no-op for users with no center areas (global
1366+
roles).</li>
1367+
</ul>
1368+
</div>
13561369
<div class="section" id="section-2">
13571370
<h1>19.0.2.0.3</h1>
13581371
<ul class="simple">

0 commit comments

Comments
 (0)