Fix common third-party logo URL not-found error

CommonThirdParty.AuthorizationAttributes returned an empty map, but
the IAM authorizer requires an entry for every requested resource ID
and treats missing entries as ErrResourceNotFound. With the new
authorize() guard on commonThirdPartyResolver.LogoURL, this surfaced
as "commonThirdParties[*].logoUrl resource not found" from the
CommonThirdPartyComboboxQuery.

Switch AuthorizationAttributes to a SELECT-by-id existence check that
returns an empty attributes map for each row that exists. The catalog
is global with no organization, so omitting organization_id is the
intended shape: the authorizer then loads no membership, evaluates
only identity-scoped policies (CommonThirdPartyCatalogPolicy grants
access), and skips audit logging.

Add an e2e regression test that seeds a CommonThirdParty directly via
the test database and asserts the GraphQL logoUrl path resolves
without error.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-05-26 19:47:36 +02:00
parent 448b5a043e
commit e6f7884a29
2 changed files with 148 additions and 5 deletions

View File

@@ -55,16 +55,46 @@ type (
CommonThirdParties []*CommonThirdParty
)
// AuthorizationAttributes is a no-op resource-attribute loader: the
// common third-party catalog is global (shared across every tenant) and
// has no organization_id. Authorization for these rows is granted by an
// identity-scoped policy that has no condition.
// AuthorizationAttributes loads existence-only attributes for the global
// common third-party catalog: rows have no organization_id, and the
// identity-scoped policy that grants access has no condition. The
// authorizer still requires an entry per requested ID (missing entries are
// treated as ErrResourceNotFound), so this verifies existence and returns
// empty attribute maps for every row that exists.
func (t *CommonThirdParty) AuthorizationAttributes(
ctx context.Context,
conn pg.Querier,
resourceIDs []gid.GID,
) (policy.AttributesByID, error) {
return map[gid.GID]policy.Attributes{}, nil
q := `SELECT id FROM common_third_parties WHERE id = ANY(@resource_ids::text[])`
args := pgx.StrictNamedArgs{
"resource_ids": resourceIDs,
}
rows, err := conn.Query(ctx, q, args)
if err != nil {
return nil, fmt.Errorf("cannot query common third party authorization attributes: %w", err)
}
defer rows.Close()
attrsByID := make(policy.AttributesByID)
for rows.Next() {
var id gid.GID
if err := rows.Scan(&id); err != nil {
return nil, fmt.Errorf("cannot scan common third party authorization attributes: %w", err)
}
attrsByID[id] = policy.Attributes{}
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("cannot iterate common third party authorization attributes: %w", err)
}
return attrsByID, nil
}
func (t *CommonThirdParty) LoadByID(