Visão geral
Hoje tokensMiddleware([TIPOS_USUARIOS.CURADOR, …]) em src/routes/*.js. Depois de /auth/*, as rotas passam a authenticate + authorize(action, resource) nos dois stacks. Esta issue só o mecanismo + um modelo; famílias nas #518–#523.
_spec/auth-and-authorization.md §10.
Fora de escopo
- Migrar todas as famílias
- Remover
POST /login
- Carregar entidade dentro do
authorize da rota
- Painel
Critérios de aceite
Detalhes técnicos
Fluxo: verificar JWT → linha em usuarios_sessoes existe → usuário ativo → createRules(user) → new Manager({ rules }) em request.user e request.auth. Nunca autorizar com rules enviadas pelo cliente.
Legado:
app.route('/tombos')
.post([
authenticate,
authorize('create', 'Tombo'),
validacoesMiddleware(cadastrarTomboEsquema),
cadastro,
])
Não adicionar request.usuario.
Novo (src/application/*, chain em ExpressApplication.endpoint):
{
method: Method.Post,
path: '/v1/tombos',
handlers: [
authenticate,
authorize('create', 'Tombo'),
new CriarTomboController({ criarTomboUseCase }),
]
}
Estender HttpRequest (src/library/http/common.ts) com user e auth opcionais.
authorize na rota: só can(action, resource). Registro: use case/controller depois do find (can(action, resource, record)). Collections não autorizam.
CASL sem registro = “pode esta ação neste recurso para algum item”. Conditions de linha só depois de carregar.
Esboço authenticate (RequestHandler novo stack):
async handle(request, next) {
const token = bearer(request.headers.Authorization)
if (!token) return new UnauthorizedError({ message: '…' })
const payload = verifyAccess(token) // TokenExpiredError → código de expirado
const session = await sessions.findById(payload.sid)
if (!session) return new UnauthorizedError({ message: '…' })
const user = await users.findActive(payload.sub)
if (!user) return new UnauthorizedError({ message: '…' })
request.user = { id: user.id, nome: user.nome, email: user.email, tipo_usuario_id: user.tipo_usuario_id }
request.auth = new Manager({ rules: createRules(request.user) })
return next()
}
Esboço authorize (fábrica):
export function authorize(action: string, resource: string): RequestHandler {
return {
async handle(request, next) {
if (!request.auth?.can(action, resource)) {
return new ForbiddenError({ message: '…' })
}
return next()
},
}
}
Use case (depois do load):
const tombo = await collection.findByHcf(hcf)
if (!tombo) return notFound
if (!auth.can('update', 'Tombo', tombo)) return forbidden
Visão geral
Hoje
tokensMiddleware([TIPOS_USUARIOS.CURADOR, …])emsrc/routes/*.js. Depois de/auth/*, as rotas passam aauthenticate+authorize(action, resource)nos dois stacks. Esta issue só o mecanismo + um modelo; famílias nas #518–#523._spec/auth-and-authorization.md§10.Fora de escopo
POST /loginauthorizeda rotaCritérios de aceite
authenticateno legado (Express) e comoRequestHandlerno/v1authorize('create', 'Tombo')(exemplo) recusa sem registro; 403 viaForbiddenError/v1usam o par como modeloGET /v1/paiseseGET /v1/estadoscontinuam públicosDetalhes técnicos
Fluxo: verificar JWT → linha em
usuarios_sessoesexiste → usuárioativo→createRules(user)→new Manager({ rules })emrequest.usererequest.auth. Nunca autorizar comrulesenviadas pelo cliente.Legado:
Não adicionar
request.usuario.Novo (
src/application/*, chain emExpressApplication.endpoint):Estender
HttpRequest(src/library/http/common.ts) comusereauthopcionais.authorizena rota: sócan(action, resource). Registro: use case/controller depois dofind(can(action, resource, record)). Collections não autorizam.CASL sem registro = “pode esta ação neste recurso para algum item”. Conditions de linha só depois de carregar.
Esboço
authenticate(RequestHandler novo stack):Esboço
authorize(fábrica):Use case (depois do load):