af2366acb5
Fase 5 del issue 0010 — RBAC y middlewares de auth.
- rbac_check es pura: solo recorre la matriz roles/permisos
- jwt_middleware extrae token del header Authorization: Bearer, valida e
inyecta claims en el context con una key privada (jwtCtxKey struct{})
- rbac_middleware requiere jwt_middleware antes; lee role de claims.Custom
- Helper JWTClaimsFromContext para acceder a las claims desde handlers
- 401 claro si RBAC se usa sin JWT antes (code: no_claims)
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
package infra
|
|
|
|
import "testing"
|
|
|
|
func makeRoles() []Role {
|
|
return []Role{
|
|
{
|
|
Name: "admin",
|
|
Permissions: []Permission{
|
|
{Resource: "users", Action: "read"},
|
|
{Resource: "users", Action: "write"},
|
|
{Resource: "users", Action: "delete"},
|
|
},
|
|
},
|
|
{
|
|
Name: "viewer",
|
|
Permissions: []Permission{
|
|
{Resource: "users", Action: "read"},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestRBACCheck_Granted(t *testing.T) {
|
|
roles := makeRoles()
|
|
if !RBACCheck(roles, "admin", Permission{Resource: "users", Action: "delete"}) {
|
|
t.Fatal("admin deberia tener users/delete")
|
|
}
|
|
if !RBACCheck(roles, "viewer", Permission{Resource: "users", Action: "read"}) {
|
|
t.Fatal("viewer deberia tener users/read")
|
|
}
|
|
}
|
|
|
|
func TestRBACCheck_Denied(t *testing.T) {
|
|
roles := makeRoles()
|
|
if RBACCheck(roles, "viewer", Permission{Resource: "users", Action: "delete"}) {
|
|
t.Fatal("viewer NO deberia tener users/delete")
|
|
}
|
|
}
|
|
|
|
func TestRBACCheck_UnknownRole(t *testing.T) {
|
|
roles := makeRoles()
|
|
if RBACCheck(roles, "ghost", Permission{Resource: "users", Action: "read"}) {
|
|
t.Fatal("rol inexistente no deberia tener permisos")
|
|
}
|
|
}
|
|
|
|
func TestRBACCheck_ExactMatch(t *testing.T) {
|
|
roles := makeRoles()
|
|
// Resource distinto
|
|
if RBACCheck(roles, "admin", Permission{Resource: "billing", Action: "read"}) {
|
|
t.Fatal("admin no tiene billing/read")
|
|
}
|
|
// Action distinta
|
|
if RBACCheck(roles, "viewer", Permission{Resource: "users", Action: "write"}) {
|
|
t.Fatal("viewer no tiene users/write")
|
|
}
|
|
}
|