Files
zeekay 1943f1c093 Hanzo Commerce
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans,
usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0.

Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
2026-09-23 21:52:16 -07:00

43 lines
1.8 KiB
Go

// Copyright (c) 2014-present Hanzo AI, Inc.
// Licensed under MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.
//
// Package organization — M1 regression: the "platform" org-name namespace
// bypass is gone.
//
// Previously Organization.Namespace() returned "" (the global/cross-org
// datastore namespace where every org's records live) when Name=="platform",
// keyed purely on an org-NAME string and fully decoupled from real
// platform-admin identity. Anyone who could land in (or forge owner=) an org
// named "platform" got a cross-org datastore view (Red — privilege escalation
// via the empty namespace). Cross-org access is now gated EXCLUSIVELY on
// auth.IAMClaims.IsSuperAdmin() at the handler layer; the model never grants it
// by name.
package organization
import "testing"
// TestNamespace_NoPlatformBypass pins the fix: "platform" is just another org
// name, strictly scoped to itself — never the empty/global namespace.
func TestNamespace_NoPlatformBypass(t *testing.T) {
if ns := (Organization{Name: "platform"}).Namespace(); ns != "platform" {
t.Fatalf("platform org namespace = %q, want \"platform\" (empty-namespace bypass must be removed)", ns)
}
}
// TestNamespace_StrictScoping proves ordinary orgs are scoped to their own
// name, and an empty name maps to the empty namespace with no special-casing.
func TestNamespace_StrictScoping(t *testing.T) {
cases := map[string]string{
"maxpower": "maxpower",
"hanzo": "hanzo",
"admin": "admin", // even the global-admin org is name-scoped here;
// cross-org access is granted by IsSuperAdmin(), not by Namespace().
"": "",
}
for name, want := range cases {
if got := (Organization{Name: name}).Namespace(); got != want {
t.Errorf("Organization{Name:%q}.Namespace() = %q, want %q", name, got, want)
}
}
}