package acl import ( "testing" ) func TestEmptyACL_AllowsEverything(t *testing.T) { a := FromMap(nil) if !a.Empty() { t.Fatal("expected empty ACL") } if !a.CanDo("@anyone:server", "anything") { t.Fatal("empty ACL should allow everything") } } func TestCanDo_AdminWildcard(t *testing.T) { a := FromMap(map[string]RoleDef{ "admin": { Users: []string{"@admin:server"}, Actions: []string{"*"}, }, }) if !a.CanDo("@admin:server", "command:deploy") { t.Fatal("admin should be able to do anything") } if a.CanDo("@user:server", "command:deploy") { t.Fatal("unknown user should be denied when roles are defined") } } func TestCanDo_SpecificActions(t *testing.T) { a := FromMap(map[string]RoleDef{ "admin": { Users: []string{"@admin:server"}, Actions: []string{"*"}, }, "user": { Users: []string{"*"}, Actions: []string{"ask", "help", "command:help", "command:ping"}, }, }) // Admin can do anything if !a.CanDo("@admin:server", "tool:ssh_command") { t.Fatal("admin should have wildcard access") } // Regular user can ask and use help if !a.CanDo("@random:server", "ask") { t.Fatal("wildcard user should be able to ask") } if !a.CanDo("@random:server", "command:help") { t.Fatal("wildcard user should be able to use help command") } // Regular user cannot use restricted tools if a.CanDo("@random:server", "tool:ssh_command") { t.Fatal("wildcard user should not access ssh tool") } if a.CanDo("@random:server", "command:deploy") { t.Fatal("wildcard user should not access deploy command") } } func TestCanDo_PrefixWildcard(t *testing.T) { a := FromMap(map[string]RoleDef{ "ops": { Users: []string{"@ops:server"}, Actions: []string{"command:*", "tool:*"}, }, }) if !a.CanDo("@ops:server", "command:deploy") { t.Fatal("command:* should match command:deploy") } if !a.CanDo("@ops:server", "tool:ssh_command") { t.Fatal("tool:* should match tool:ssh_command") } if a.CanDo("@ops:server", "ask") { t.Fatal("command:*/tool:* should not match 'ask'") } } func TestRoleFor_ExactBeforeWildcard(t *testing.T) { a := FromMap(map[string]RoleDef{ "admin": { Users: []string{"@admin:server"}, Actions: []string{"*"}, }, "user": { Users: []string{"*"}, Actions: []string{"ask"}, }, }) if role := a.RoleFor("@admin:server"); role != "admin" { t.Fatalf("expected admin, got %q", role) } if role := a.RoleFor("@random:server"); role != "user" { t.Fatalf("expected user, got %q", role) } if role := a.RoleFor("@nobody:other"); role != "user" { t.Fatalf("expected user for wildcard, got %q", role) } } func TestRoleFor_NoMatch(t *testing.T) { a := FromMap(map[string]RoleDef{ "admin": { Users: []string{"@admin:server"}, Actions: []string{"*"}, }, }) if role := a.RoleFor("@nobody:server"); role != "" { t.Fatalf("expected empty role, got %q", role) } } func TestAllowedUsers(t *testing.T) { a := FromMap(map[string]RoleDef{ "admin": { Users: []string{"@admin:server", "@root:server"}, Actions: []string{"*"}, }, "user": { Users: []string{"*", "@admin:server"}, // admin appears in both Actions: []string{"ask"}, }, }) users := a.AllowedUsers() // Should contain @admin:server and @root:server, deduplicated, no "*" if len(users) != 2 { t.Fatalf("expected 2 users, got %d: %v", len(users), users) } found := make(map[string]bool) for _, u := range users { found[u] = true } if !found["@admin:server"] || !found["@root:server"] { t.Fatalf("unexpected users: %v", users) } } func TestCanDo_MultipleRolesForSameUser(t *testing.T) { a := FromMap(map[string]RoleDef{ "viewer": { Users: []string{"@user:server"}, Actions: []string{"ask", "help"}, }, "deployer": { Users: []string{"@user:server"}, Actions: []string{"command:deploy"}, }, }) // User has both roles, should be able to do actions from either if !a.CanDo("@user:server", "ask") { t.Fatal("user should be able to ask via viewer role") } if !a.CanDo("@user:server", "command:deploy") { t.Fatal("user should be able to deploy via deployer role") } if a.CanDo("@user:server", "tool:ssh_command") { t.Fatal("user should not have ssh access") } }