Check the scope owner exists when creating a scope-bound entity
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
## Objective
A scope-bound create accepts a scope owner that does not exist. Observed on a live server: creating an AppConfigFragment at scope_type=user with a user id that no user row carries succeeds and leaves a row bound to a scope element nobody can reach. Searching that same scope answers 404 UserNotFound, so the write and the read disagree about whether the scope exists.
The read path already has the machinery: SearchScope.existence_checks declares one ExistenceCheck per scope owner and the batch querier validates them in a single EXISTS query before running. The write path has no equivalent, so RBACEntityCreator writes an association row pointing at an element id that matches nothing.
## Deliverables
- Lift the existence-check validation out of the querier into a shared helper so both the read and the write path use one implementation.
- Let RBACEntityCreator carry existence checks and validate them before the insert, so the create fails with the owner's own not-found error rather than succeeding.
- Declare the checks for the AppConfigFragment create, reusing the same definition its scoped search already uses so the two cannot drift.
## Acceptance Criteria
- Creating a fragment at a domain or user scope whose owner does not exist raises the same error the scoped search raises for that scope (DomainNotFound / UserNotFound), and writes no row.
- Public scope, which has no owner, keeps creating without an extra query.
- A creator that declares no checks issues no additional query, so entities that have not adopted this are unaffected.
- Repository-level test covering both the rejected create and the still-working public create.
## Background
Found while exercising the AppConfigFragment GraphQL surface against a live server (BA-6977 / BA-6984). Only a superadmin can name someone else's scope on a create, so the exposure is narrow, but the orphan row it leaves is invisible to every read path.
JIRA Issue: BA-6985
Contributor guide
Research direction
Start by locating SearchScope.existence_checks, the batch querier's validation, RBACEntityCreator, and the AppConfigFragment create and scoped-search definitions. Extract the shared validation, apply the declared checks before insertion, and add repository-level coverage showing rejected domain/user creates, successful public creates, and no extra query when checks are absent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, python
- Domain
- authorization, backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 62/100