--- name: rbac_middleware kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func RBACMiddleware(roles []Role, required Permission) Middleware" description: "Middleware HTTP que verifica que el usuario autenticado tenga un permiso concreto. Lee las claims del context (puestas por JWTMiddleware), extrae el rol de claims.Custom[role] y evalua con RBACCheck. Responde 403 si no tiene permiso, 401 si no hay claims." tags: [rbac, auth, middleware, http, server, infra, pendiente-usar] uses_functions: [rbac_check_go_infra, http_error_response_go_infra] uses_types: [Role_go_infra, Permission_go_infra, Middleware_go_infra, HTTPError_go_infra] returns: [Middleware_go_infra] returns_optional: false error_type: error_go_core imports: [net/http] params: - name: roles desc: "matriz de roles y sus permisos, usualmente hardcoded o leida de config al arrancar" - name: required desc: "permiso requerido para acceder al handler (Resource + Action)" output: "Middleware que bloquea el request con 403 si el rol del usuario no tiene el permiso requerido" tested: true tests: ["pasa con rol que tiene el permiso", "403 con rol sin permiso", "403 con rol inexistente", "401 si no hay claims en el context"] test_file_path: "functions/infra/rbac_middleware_test.go" file_path: "functions/infra/rbac_middleware.go" --- ## Ejemplo ```go roles := []Role{ {Name: "admin", Permissions: []Permission{{Resource: "users", Action: "delete"}}}, } adminProtected := HTTPMiddlewareChain( JWTMiddleware(secret), RBACMiddleware(roles, Permission{Resource: "users", Action: "delete"}), ) mux.Handle("DELETE /api/users/{id}", adminProtected(deleteUserHandler)) ``` ## Notas Impura — depende del estado del request y de JWTMiddleware. El rol se lee de `claims.Custom["role"]` como string: si la app usa otro campo (ej: `claims.Custom["roles"]` como slice) conviene crear un middleware variante. Si el usuario tiene multiples roles, extenderse iterando `RBACCheck` sobre cada uno. Orden en la chain: SIEMPRE JWTMiddleware antes — si se olvida, el middleware retorna 401 con code `no_claims` para facilitar debugging. No cachea la evaluacion: RBACCheck es O(roles*permisos) pero para listas pequeñas (<100) es despreciable.