fc644ecd6e
Reemplaza el scaffold del echobot por la plataforma completa de bots traida desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out: los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms + E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client). - go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths relativos reajustados a la nueva ubicacion dentro de fn_registry). - app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales. - modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports). agents_and_robots queda archivado como museo de la era Matrix.
172 lines
4.1 KiB
Go
172 lines
4.1 KiB
Go
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")
|
|
}
|
|
}
|