internal/middleware/tenant_test.go
Rama main · réplica de lectura del repositorio original.
package middleware
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/google/uuid"
"github.com/sarathsp06/sparrow/internal/tenant"
"github.com/sarathsp06/sparrow/pkg/access"
)
// forTenant runs the request as tenant id, as server.WithTenant does.
func forTenant(id uuid.UUID) func(*http.Request) {
return func(r *http.Request) { *r = *r.WithContext(tenant.WithTenant(r.Context(), id)) }
}
func both(sets ...func(*http.Request)) func(*http.Request) {
return func(r *http.Request) {
for _, set := range sets {
set(r)
}
}
}
func TestAuthRefusesATokenOfTenantAOnTenantB(t *testing.T) {
auth, svc := newAuth(t, "secret")
tenantA, tenantB := uuid.New(), uuid.New()
tok, secret, err := svc.CreateToken(context.Background(), access.CreateTokenRequest{Realm: tenantA.String(), Name: "a", CreatedBy: "x"})
if err != nil {
t.Fatal(err)
}
if code, p, _ := guarded(auth, both(forTenant(tenantA), apiKey(secret))); code != http.StatusNoContent || p.TokenID != tok.ID {
t.Fatalf("token on its own tenant: %d %+v", code, p)
}
if code, _, body := guarded(auth, both(forTenant(tenantB), apiKey(secret))); code != http.StatusUnauthorized {
t.Fatalf("token of tenant A on tenant B: %d %s, want 401", code, body)
}
if code, _, body := guarded(auth, apiKey(secret)); code != http.StatusUnauthorized {
t.Fatalf("token of tenant A on the default tenant: %d %s, want 401", code, body)
}
// The master key is the server's, not a tenant's.
if code, p, _ := guarded(auth, both(forTenant(tenantB), apiKey("secret"))); code != http.StatusNoContent || !p.Root {
t.Fatalf("master key on tenant B: %d %+v", code, p)
}
}
func TestAuthDisabledRunsAsTheRequestTenant(t *testing.T) {
auth, _ := newAuth(t, "")
tenantB := uuid.New()
if code, p, _ := guarded(auth, forTenant(tenantB)); code != http.StatusNoContent || p.Realm != tenantB.String() {
t.Fatalf("disabled auth on tenant B: %d %+v", code, p)
}
}
func TestPortalGatewayRefusesATokenOfTenantAOnTenantB(t *testing.T) {
svc, gw, seen := newPortalGateway(t)
tenantA, tenantB := uuid.New(), uuid.New()
acme := "acme"
_, secret, err := svc.CreateToken(context.Background(), access.CreateTokenRequest{Realm: tenantA.String(), Scope: &acme, Name: "portal", CreatedBy: "x"})
if err != nil {
t.Fatal(err)
}
call := func(id uuid.UUID) int {
req := httptest.NewRequest(http.MethodGet, "/portal/api/webhooks", nil)
req = req.WithContext(tenant.WithTenant(req.Context(), id))
req.Header.Set("Authorization", "Bearer "+secret)
rr := httptest.NewRecorder()
gw.ServeHTTP(rr, req)
return rr.Code
}
if code := call(tenantA); code != http.StatusNoContent || *seen != "/v1/consumers/acme/webhooks" {
t.Fatalf("token on its own tenant: %d %q", code, *seen)
}
*seen = ""
if code := call(tenantB); code != http.StatusUnauthorized || *seen != "" {
t.Fatalf("token of tenant A on tenant B: %d, reached %q; want 401 and nothing reached", code, *seen)
}
if code := call(tenant.DefaultTenantID); code != http.StatusUnauthorized || *seen != "" {
t.Fatalf("token of tenant A on the default tenant: %d, reached %q; want 401", code, *seen)
}
}