test(fusion_login_audit): view-visibility checks for admin vs non-admin
Asserts the smart-button and Login Activity tab fields are stripped from res.users get_view() for non-admin users, and present for Settings admins. Locks down the contract behind the groups="base.group_system" XML attributes on the form-inheritance view (the inherited view record cannot carry groups itself per CLAUDE.md rule #11; the gate must live on the inner nodes). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,3 +94,36 @@ class TestFusionLoginAuditSecurity(TransactionCase):
|
|||||||
# we would need a global rule (groups=[]) with domain [(0,'=',1)] paired
|
# we would need a global rule (groups=[]) with domain [(0,'=',1)] paired
|
||||||
# with the admin grant. That is a security-model redesign and out of
|
# with the admin grant. That is a security-model redesign and out of
|
||||||
# scope for T3. The ACL already provides the actual gate.
|
# scope for T3. The ACL already provides the actual gate.
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────────
|
||||||
|
# T14: view-level visibility checks. The smart button and the "Login
|
||||||
|
# Activity" tab on res.users are gated by groups="base.group_system"
|
||||||
|
# on the inner XML nodes (the inherited view record itself cannot
|
||||||
|
# carry groups — CLAUDE.md rule #11). Verify the gate works by asking
|
||||||
|
# for the form view as a non-admin and confirming the x_fc_* fields
|
||||||
|
# are stripped from the arch.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def test_view_hides_button_and_tab_for_non_admin(self):
|
||||||
|
"""A regular user's get_view() does not contain the x_fc_login_audit_*
|
||||||
|
fields — they live behind groups="base.group_system" XML attributes."""
|
||||||
|
view = self.env['res.users'].with_user(self.regular_user).get_view(
|
||||||
|
view_id=self.env.ref('base.view_users_form').id,
|
||||||
|
view_type='form',
|
||||||
|
)
|
||||||
|
arch = view['arch']
|
||||||
|
self.assertNotIn('x_fc_login_audit_count', arch,
|
||||||
|
"Smart-button field must not leak into non-admin view")
|
||||||
|
self.assertNotIn('x_fc_login_audit_ids', arch,
|
||||||
|
"Login Activity tab must not leak into non-admin view")
|
||||||
|
|
||||||
|
def test_view_shows_button_and_tab_for_admin(self):
|
||||||
|
"""A Settings admin DOES see both nodes."""
|
||||||
|
admin = self.env.ref('base.user_admin')
|
||||||
|
view = self.env['res.users'].with_user(admin).get_view(
|
||||||
|
view_id=self.env.ref('base.view_users_form').id,
|
||||||
|
view_type='form',
|
||||||
|
)
|
||||||
|
arch = view['arch']
|
||||||
|
self.assertIn('x_fc_login_audit_count', arch)
|
||||||
|
self.assertIn('x_fc_login_audit_ids', arch)
|
||||||
|
|||||||
Reference in New Issue
Block a user