Files
tailscale/ipn/localapi/syspolicy_api_test.go
kari-ts a89b32904f ipn/localapi: use caller scope for syspolicy requests (#21701)
This resolves unscoped policy requests to the connected user's effective
policy instead of the default scope.

Tested by changing the device-scoped AlwaysOn policy at runtime and
running tailscale syspolicy reload. Cofnirmed tailscaled immediately
enforced the updated policy with tailscale down

Updates tailscale/corp#41463

Signed-off-by: kari <kari@tailscale.com>
2026-10-08 08:35:14 -07:00

101 lines
2.2 KiB
Go

// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build !ts_omit_syspolicy
package localapi
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"tailscale.com/ipn/ipnauth"
"tailscale.com/util/httpm"
"tailscale.com/util/syspolicy/pkey"
"tailscale.com/util/syspolicy/rsop"
"tailscale.com/util/syspolicy/setting"
"tailscale.com/util/syspolicy/source"
)
func TestPolicyUsesCallerUserScope(t *testing.T) {
setting.SetDefinitionsForTest(t,
setting.NewDefinition(
pkey.ManagedByOrganizationName,
setting.UserSetting,
setting.StringValue,
),
)
const uid = "S-1-5-21-1001"
store := source.NewTestStore(t)
store.SetStrings(
source.TestSettingOf(pkey.ManagedByOrganizationName, "UserCorp"),
)
rsop.RegisterStoreForTest(t, "UserStore", setting.UserScopeOf(uid), store)
h := &Handler{
PermitRead: true,
Actor: &ipnauth.TestActor{UID: uid},
}
req := httptest.NewRequest(httpm.GET, "/localapi/v0/policy/", nil)
rec := httptest.NewRecorder()
h.servePolicy(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf(
"status = %d; want %d; body = %s",
rec.Code,
http.StatusOK,
rec.Body.String(),
)
}
if got := rec.Body.String(); !strings.Contains(got, "UserCorp") {
t.Fatalf("response does not contain user-scoped policy: %s", got)
}
}
func TestPolicyUsesDefaultScopeForEmptyUserID(t *testing.T) {
setting.SetDefinitionsForTest(t,
setting.NewDefinition(
pkey.ManagedByOrganizationName,
setting.DeviceSetting,
setting.StringValue,
),
)
store := source.NewTestStore(t)
store.SetStrings(
source.TestSettingOf(pkey.ManagedByOrganizationName, "DeviceCorp"),
)
rsop.RegisterStoreForTest(t, "DeviceStore", setting.DefaultScope(), store)
h := &Handler{
PermitRead: true,
Actor: &ipnauth.TestActor{},
}
req := httptest.NewRequest(httpm.GET, "/localapi/v0/policy/", nil)
rec := httptest.NewRecorder()
h.servePolicy(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf(
"status = %d; want %d; body = %s",
rec.Code,
http.StatusOK,
rec.Body.String(),
)
}
if got := rec.Body.String(); !strings.Contains(got, "DeviceCorp") {
t.Fatalf("response does not contain default-scope policy: %s", got)
}
}