eda6b1011a
Three follow-ups from #1350 review: 1. DELETE /organizations/:id/members/:tenant_id was un-gated, so a tenant Viewer could remove their own tenant from an org via the members endpoint and bypass the Admin+ requirement that POST /:id/leave already enforces. Gate it with g.Admin() — symmetric with /leave. 2. isOwnerTenant() returned (false, err) when the owner user lookup failed, and the two call sites only checked the bool. A deleted / unreadable owner user would silently fall through and let admins remove or re-role the would-be owner tenant. Make the helper fail-closed: any lookup error now returns (true, err), and both call sites refuse the destructive op on error. 3. POST /:id/request-upgrade was un-gated. Approval of the request changes the whole tenant's org role, so it is in the same trust tier as join/leave/create. Add g.Admin().