You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
spp_api_v2_programs: program references are name slugs resolved with =ilike + limit=1 — hyphenated names never resolve, case variants can resolve to the wrong program #562
Program references are built as Program/urn:openspp:program|<name lowercased, spaces → ->
(ProgramMembershipService._build_program_reference), and resolved by reversing the slug
(ProgramService.find_by_identifier: value.replace("-", " "), name =ilike, limit=1). The spp.program.id
model the code checks for does not exist in this repo, so the slug path is always used.
A program whose name contains a hyphen never round-trips, so its reference returns 404 on ?program= / POST / PUT ("Cash-Plus" → slug cash-plus → searched as "cash plus").
Program-name uniqueness is case-sensitive, so "Cash Transfer" and "CASH TRANSFER" can coexist; both slug to cash-transfer and =ilike + limit=1 picks one. Since PR fix(api_v2): REST API v2 defects found by the OpenFn adaptor (#554) #555, ?program= selects which membership a GET/PUT /ProgramMembership acts on, so a wrong resolution updates the wrong program's membership (the PUT
identity guard passes because the body resolves to the same wrong program).
Proposal
Give programs a stable external identifier (e.g. a program code / spp.program.id), use it in references, and resolve
exactly (409 on multiple matches). Keep slug resolution only as a deprecated fallback, refusing ambiguity.
Context
Found in the adversarial review of PR #555 (#554); pre-existing, but load-bearing since ?program=.
Problem
Program references are built as
Program/urn:openspp:program|<name lowercased, spaces → ->(
ProgramMembershipService._build_program_reference), and resolved by reversing the slug(
ProgramService.find_by_identifier:value.replace("-", " "),name =ilike,limit=1). Thespp.program.idmodel the code checks for does not exist in this repo, so the slug path is always used.
?program=/POST/PUT("Cash-Plus"→ slugcash-plus→ searched as"cash plus")."Cash Transfer"and"CASH TRANSFER"can coexist; both slug tocash-transferand=ilike+limit=1picks one. Since PR fix(api_v2): REST API v2 defects found by the OpenFn adaptor (#554) #555,?program=selects which membership aGET/PUT /ProgramMembershipacts on, so a wrong resolution updates the wrong program's membership (the PUTidentity guard passes because the body resolves to the same wrong program).
Proposal
Give programs a stable external identifier (e.g. a program code /
spp.program.id), use it in references, and resolveexactly (409 on multiple matches). Keep slug resolution only as a deprecated fallback, refusing ambiguity.
Context
Found in the adversarial review of PR #555 (#554); pre-existing, but load-bearing since
?program=.