mirror of
https://github.com/hanzoai/commerce.git
synced 2026-10-30 15:08:42 +00:00
Claims read from the identity headers fell back to X-Org-Id for the home org whenever X-User-Owner was absent. The boundary mints X-User-Owner for every principal it validates, so an absent one means no validated home, and X-Org-Id is then only the org the request named. Such claims now carry Attested, and homeOrg reads their home from X-User-Owner alone. The JWT path, where Owner is the owner claim, is unchanged. Claude-Session: https://claude.ai/code/session_01HuMDfgFssPUptYUzgZ6Cp8
43 lines
1.6 KiB
Go
43 lines
1.6 KiB
Go
// Copyright (c) 2014-present Hanzo AI, Inc.
|
|
// Licensed under MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.
|
|
|
|
package iammiddleware
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/zap-proto/zip"
|
|
)
|
|
|
|
// TestGetIAMClaims_HomeIsWhatTheBoundaryAttests: SuperAdmin is read from the home
|
|
// org the identity boundary attests (X-User-Owner) and from nothing else. A
|
|
// request the boundary validated nobody on carries only the caller's own
|
|
// X-Org-Id, and naming the reserved org there grants nothing.
|
|
func TestGetIAMClaims_HomeIsWhatTheBoundaryAttests(t *testing.T) {
|
|
app := zip.New(zip.Config{DisableStartupMessage: true})
|
|
cases := []struct {
|
|
name string
|
|
headers map[string]string
|
|
want bool
|
|
}{
|
|
{"nobody validated, X-Org-Id admin", map[string]string{"X-Org-Id": "admin"}, false},
|
|
{"nobody validated, X-Org-Id Admin", map[string]string{"X-Org-Id": "Admin"}, false},
|
|
{"home admin", map[string]string{"X-User-Owner": "admin", "X-Org-Id": "admin"}, true},
|
|
{"home admin, switched into a tenant", map[string]string{"X-User-Owner": "admin", "X-Org-Id": "acme"}, true},
|
|
{"home brand org, X-Org-Id admin", map[string]string{"X-User-Owner": "hanzo", "X-Org-Id": "admin"}, false},
|
|
{"org admin of its own org", map[string]string{"X-User-Owner": "acme", "X-Org-Id": "acme", HeaderUserIsAdmin: "true"}, false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := app.TestCtx(http.MethodPut, "/v1/commerce/plans/entries/dev")
|
|
for k, v := range tc.headers {
|
|
c.Fiber().Request().Header.Set(k, v)
|
|
}
|
|
if got := GetIAMClaims(c).IsSuperAdmin(); got != tc.want {
|
|
t.Fatalf("IsSuperAdmin()=%v want %v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|