allow users to be defined with @ in v1 (#2495)
* allow users to be defined with @ in v1 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * remove integration test rewrite hack Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * remove test rewrite hack Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * add @ to integration tests Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * a bit to agressive removeals Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * fix last test Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> --------- Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
f52f15ff08
commit
e3521be705
12 changed files with 76 additions and 150 deletions
|
@ -137,13 +137,13 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user1:*"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user1@:*"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user2"},
|
||||
Destinations: []string{"user2:*"},
|
||||
Sources: []string{"user2@"},
|
||||
Destinations: []string{"user2@:*"},
|
||||
},
|
||||
},
|
||||
}, want: map[string]int{
|
||||
|
@ -160,23 +160,23 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user1:22"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user1@:22"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user2"},
|
||||
Destinations: []string{"user2:22"},
|
||||
Sources: []string{"user2@"},
|
||||
Destinations: []string{"user2@:22"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user2:22"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user2@:22"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user2"},
|
||||
Destinations: []string{"user1:22"},
|
||||
Sources: []string{"user2@"},
|
||||
Destinations: []string{"user1@:22"},
|
||||
},
|
||||
},
|
||||
}, want: map[string]int{
|
||||
|
@ -194,18 +194,18 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user1:*"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user1@:*"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user2"},
|
||||
Destinations: []string{"user2:*"},
|
||||
Sources: []string{"user2@"},
|
||||
Destinations: []string{"user2@:*"},
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user2:*"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user2@:*"},
|
||||
},
|
||||
},
|
||||
}, want: map[string]int{
|
||||
|
@ -219,18 +219,18 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: append([]string{"user1:*"}, veryLargeDestination...),
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: append([]string{"user1@:*"}, veryLargeDestination...),
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user2"},
|
||||
Destinations: append([]string{"user2:*"}, veryLargeDestination...),
|
||||
Sources: []string{"user2@"},
|
||||
Destinations: append([]string{"user2@:*"}, veryLargeDestination...),
|
||||
},
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: append([]string{"user2:*"}, veryLargeDestination...),
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: append([]string{"user2@:*"}, veryLargeDestination...),
|
||||
},
|
||||
},
|
||||
}, want: map[string]int{
|
||||
|
@ -299,8 +299,8 @@ func TestACLAllowUser80Dst(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user2:80"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user2@:80"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -351,7 +351,7 @@ func TestACLDenyAllPort80(t *testing.T) {
|
|||
scenario := aclScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-acl-test": {"user1", "user2"},
|
||||
"group:integration-acl-test": {"user1@", "user2@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -400,8 +400,8 @@ func TestACLAllowUserDst(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user2:*"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user2@:*"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -456,7 +456,7 @@ func TestACLAllowStarDst(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"*:*"},
|
||||
},
|
||||
},
|
||||
|
@ -912,8 +912,8 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
|||
"group": {
|
||||
policy: policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:one": {"user1"},
|
||||
"group:two": {"user2"},
|
||||
"group:one": {"user1@"},
|
||||
"group:two": {"user2@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -1079,15 +1079,12 @@ func TestPolicyUpdateWhileRunningWithCLIInDatabase(t *testing.T) {
|
|||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
Destinations: []string{"user2:*"},
|
||||
Sources: []string{"user1@"},
|
||||
Destinations: []string{"user2@:*"},
|
||||
},
|
||||
},
|
||||
Hosts: policyv1.Hosts{},
|
||||
}
|
||||
if usePolicyV2ForTest {
|
||||
hsic.RewritePolicyToV2(&p)
|
||||
}
|
||||
|
||||
pBytes, _ := json.Marshal(p)
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ func TestPreAuthKeyCommand(t *testing.T) {
|
|||
keys := make([]*v1.PreAuthKey, count)
|
||||
assertNoErr(t, err)
|
||||
|
||||
for index := 0; index < count; index++ {
|
||||
for index := range count {
|
||||
var preAuthKey v1.PreAuthKey
|
||||
err := executeAndUnmarshal(
|
||||
headscale,
|
||||
|
@ -639,7 +639,7 @@ func TestApiKeyCommand(t *testing.T) {
|
|||
|
||||
keys := make([]string, count)
|
||||
|
||||
for idx := 0; idx < count; idx++ {
|
||||
for idx := range count {
|
||||
apiResult, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
|
@ -716,7 +716,7 @@ func TestApiKeyCommand(t *testing.T) {
|
|||
expiredPrefixes := make(map[string]bool)
|
||||
|
||||
// Expire three keys
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
for idx := range 3 {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
|
@ -951,7 +951,7 @@ func TestNodeAdvertiseTagCommand(t *testing.T) {
|
|||
},
|
||||
},
|
||||
TagOwners: map[string][]string{
|
||||
"tag:test": {"user1"},
|
||||
"tag:test": {"user1@"},
|
||||
},
|
||||
},
|
||||
wantTag: true,
|
||||
|
@ -960,7 +960,7 @@ func TestNodeAdvertiseTagCommand(t *testing.T) {
|
|||
name: "with-policy-groups",
|
||||
policy: &policyv1.ACLPolicy{
|
||||
Groups: policyv1.Groups{
|
||||
"group:admins": []string{"user1"},
|
||||
"group:admins": []string{"user1@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -1357,7 +1357,7 @@ func TestNodeExpireCommand(t *testing.T) {
|
|||
assert.True(t, listAll[3].GetExpiry().AsTime().IsZero())
|
||||
assert.True(t, listAll[4].GetExpiry().AsTime().IsZero())
|
||||
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
for idx := range 3 {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
|
@ -1484,7 +1484,7 @@ func TestNodeRenameCommand(t *testing.T) {
|
|||
assert.Contains(t, listAll[3].GetGivenName(), "node-4")
|
||||
assert.Contains(t, listAll[4].GetGivenName(), "node-5")
|
||||
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
for idx := range 3 {
|
||||
res, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
|
@ -1751,12 +1751,9 @@ func TestPolicyCommand(t *testing.T) {
|
|||
},
|
||||
},
|
||||
TagOwners: map[string][]string{
|
||||
"tag:exists": {"user1"},
|
||||
"tag:exists": {"user1@"},
|
||||
},
|
||||
}
|
||||
if usePolicyV2ForTest {
|
||||
hsic.RewritePolicyToV2(&p)
|
||||
}
|
||||
|
||||
pBytes, _ := json.Marshal(p)
|
||||
|
||||
|
@ -1797,11 +1794,6 @@ func TestPolicyCommand(t *testing.T) {
|
|||
|
||||
assert.Len(t, output.TagOwners, 1)
|
||||
assert.Len(t, output.ACLs, 1)
|
||||
if usePolicyV2ForTest {
|
||||
assert.Equal(t, output.TagOwners["tag:exists"], []string{"user1@"})
|
||||
} else {
|
||||
assert.Equal(t, output.TagOwners["tag:exists"], []string{"user1"})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPolicyBrokenConfigCommand(t *testing.T) {
|
||||
|
@ -1840,12 +1832,9 @@ func TestPolicyBrokenConfigCommand(t *testing.T) {
|
|||
},
|
||||
},
|
||||
TagOwners: map[string][]string{
|
||||
"tag:exists": {"user1"},
|
||||
"tag:exists": {"user1@"},
|
||||
},
|
||||
}
|
||||
if usePolicyV2ForTest {
|
||||
hsic.RewritePolicyToV2(&p)
|
||||
}
|
||||
|
||||
pBytes, _ := json.Marshal(p)
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ func TestTaildrop(t *testing.T) {
|
|||
|
||||
retry := func(times int, sleepInterval time.Duration, doWork func() error) error {
|
||||
var err error
|
||||
for attempts := 0; attempts < times; attempts++ {
|
||||
for range times {
|
||||
err = doWork()
|
||||
if err == nil {
|
||||
return nil
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"net/netip"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -413,10 +412,6 @@ func New(
|
|||
}
|
||||
|
||||
if hsic.aclPolicy != nil {
|
||||
// Rewrite all user entries in the policy to have an @ at the end.
|
||||
if hsic.policyV2 {
|
||||
RewritePolicyToV2(hsic.aclPolicy)
|
||||
}
|
||||
data, err := json.Marshal(hsic.aclPolicy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal ACL Policy to JSON: %w", err)
|
||||
|
@ -878,50 +873,3 @@ func (t *HeadscaleInContainer) SendInterrupt() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(kradalby): Remove this function when v1 is deprecated
|
||||
func rewriteUsersToV2(strs []string) []string {
|
||||
var result []string
|
||||
userPattern := regexp.MustCompile(`^user\d+$`)
|
||||
|
||||
for _, username := range strs {
|
||||
parts := strings.Split(username, ":")
|
||||
if len(parts) == 0 {
|
||||
result = append(result, username)
|
||||
continue
|
||||
}
|
||||
firstPart := parts[0]
|
||||
if userPattern.MatchString(firstPart) {
|
||||
modifiedFirst := firstPart + "@"
|
||||
if len(parts) > 1 {
|
||||
rest := strings.Join(parts[1:], ":")
|
||||
username = modifiedFirst + ":" + rest
|
||||
} else {
|
||||
username = modifiedFirst
|
||||
}
|
||||
}
|
||||
result = append(result, username)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// rewritePolicyToV2 rewrites the policy to v2 format.
|
||||
// This mostly means adding the @ prefix to user names.
|
||||
// replaces are done inplace
|
||||
func RewritePolicyToV2(pol *policyv1.ACLPolicy) {
|
||||
for idx := range pol.ACLs {
|
||||
pol.ACLs[idx].Sources = rewriteUsersToV2(pol.ACLs[idx].Sources)
|
||||
pol.ACLs[idx].Destinations = rewriteUsersToV2(pol.ACLs[idx].Destinations)
|
||||
}
|
||||
for idx := range pol.Groups {
|
||||
pol.Groups[idx] = rewriteUsersToV2(pol.Groups[idx])
|
||||
}
|
||||
for idx := range pol.TagOwners {
|
||||
pol.TagOwners[idx] = rewriteUsersToV2(pol.TagOwners[idx])
|
||||
}
|
||||
for idx := range pol.SSHs {
|
||||
pol.SSHs[idx].Sources = rewriteUsersToV2(pol.SSHs[idx].Sources)
|
||||
pol.SSHs[idx].Destinations = rewriteUsersToV2(pol.SSHs[idx].Destinations)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -796,7 +796,7 @@ func TestEnableDisableAutoApprovedRoute(t *testing.T) {
|
|||
},
|
||||
},
|
||||
TagOwners: map[string][]string{
|
||||
"tag:approve": {"user1"},
|
||||
"tag:approve": {"user1@"},
|
||||
},
|
||||
AutoApprovers: policyv1.AutoApprovers{
|
||||
Routes: map[string][]string{
|
||||
|
@ -901,7 +901,7 @@ func TestAutoApprovedSubRoute2068(t *testing.T) {
|
|||
},
|
||||
},
|
||||
TagOwners: map[string][]string{
|
||||
"tag:approve": {user},
|
||||
"tag:approve": {user + "@"},
|
||||
},
|
||||
AutoApprovers: policyv1.AutoApprovers{
|
||||
Routes: map[string][]string{
|
||||
|
@ -964,7 +964,7 @@ func TestSubnetRouteACL(t *testing.T) {
|
|||
}, hsic.WithTestName("clienableroute"), hsic.WithACLPolicy(
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: policyv1.Groups{
|
||||
"group:admins": {user},
|
||||
"group:admins": {user + "@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ var retry = func(times int, sleepInterval time.Duration,
|
|||
var stderr string
|
||||
var err error
|
||||
|
||||
for attempts := 0; attempts < times; attempts++ {
|
||||
for range times {
|
||||
tempResult, tempStderr, err := doWork()
|
||||
|
||||
result += tempResult
|
||||
|
@ -94,7 +94,7 @@ func TestSSHOneUserToAll(t *testing.T) {
|
|||
scenario := sshScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
"group:integration-test": {"user1@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ func TestSSHMultipleUsersAllToAll(t *testing.T) {
|
|||
scenario := sshScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1", "user2"},
|
||||
"group:integration-test": {"user1@", "user2@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ func TestSSHNoSSHConfigured(t *testing.T) {
|
|||
scenario := sshScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
"group:integration-test": {"user1@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -254,7 +254,7 @@ func TestSSHIsBlockedInACL(t *testing.T) {
|
|||
scenario := sshScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
"group:integration-test": {"user1@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
@ -303,8 +303,8 @@ func TestSSHUserOnlyIsolation(t *testing.T) {
|
|||
scenario := sshScenario(t,
|
||||
&policyv1.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:ssh1": {"user1"},
|
||||
"group:ssh2": {"user2"},
|
||||
"group:ssh1": {"user1@"},
|
||||
"group:ssh2": {"user2@"},
|
||||
},
|
||||
ACLs: []policyv1.ACL{
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue