Repository navigation
TIGER-410: enforce the ACL §1a role-scope standard in code (Service primitive + Media + blog taxonomy) - #381
Merged
Conversation
The §1a "role scope as the standard" doc shipped (PR #373); this is the code that enforces it. - Tiger_Service gains the one org-scope authority: RESOURCE_ALL_ORGS + _orgId()/_orgScope()/_inOrgScope(). _orgScope() returns null (no predicate = app-wide) or [ownOrg, ''] (own org + global rows); the ACL resource Tiger_Tenancy_AllOrgs (read -> role admin) decides which, so it is role configuration, not an if-on-role. - Media (Tiger_Model_Media + modules/media) and blog taxonomy (modules/blog) move off hard single-org scoping onto the shared primitive, so an app-wide admin is no longer walled out of orgs it administers while tenants stay isolated from each other. Generalizes the narrower TIGER-64 media scoping. - tests/Unit/Service/OrgScopeTest.php. Sibling TIGER-391 (CMS surface still hard-scoped) is not covered here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ
…dia) The two media cross-tenant cases asserted the PRE-§1a rule (an admin is refused on another org's row). §1a makes "reach every org" a CAPABILITY granted at `admin` in core, and media is an admin-gated feature, so an app-wide admin legitimately manages every org's media — the cases now assert that (crosses + mutates/removes B's row). The tenant WALL (a role without the capability is scoped to its own org) is pinned at the primitive in Unit/Service/OrgScopeTest, where that decision lives. The cms-menu cases still assert denial: Cms_Service_Menu is out of scope for TIGER-410 and not yet converted, so they pin its current behaviour. Class docblock rewritten to say all of this. Fixes the integration + coverage CI failures (the only two reds on this PR). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the ACL §1a "role scope as the standard" doc (merged in PR #373) — the standard shipped, the enforcing code did not. [TIGER-410]
What
A single org-scope authority on
Tiger_Service:RESOURCE_ALL_ORGS+_orgId()/_orgScope()/_inOrgScope()._orgScope()returns null (no predicate = app-wide) or[ownOrg, ''](own org + global rows).Tiger_Tenancy_AllOrgs(readgranted to roleadmin, so superadmin/developer inherit; manager/supermanager don't) decides which — role configuration, not anif-on-role.Callers moved onto the primitive:
Tiger_Model_Media::datatable()takesorg_scope(array | null) instead of a hardorg_id;modules/mediarow/manage guards use_inOrgScope(). Generalizes the narrower TIGER-64 single-org scoping.modules/blogvocabulary listing treats null as app-wide, array as explicit scope.New:
tests/Unit/Service/OrgScopeTest.php.Why
Multi-tenant isolation must hold for normal users (own org only), but the prior hard
org_idscoping also walled app-wide admins out of the orgs they administer. One authority both callers use, per the no-$db-predicates-in-services convention.Scope
Covers the shared
Serviceprimitive + Media + blog taxonomy. Sibling TIGER-391 (CMS surface still hard-scoped) is NOT in this PR.Provenance
Recovered from uncommitted work that was sitting on an unrelated (already-merged) branch; lifted cleanly onto
origin/mainvia a fresh branch.php -lclean; full suite runs in CI.🤖 Generated with Claude Code
https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ