Redefinir Senha de Usuário (Admin / root)¶
Status: mecanismo interino via CRUD genérico — não há endpoint dedicado. Funcional e com authz corrigida em 2026-05-18 (DEBT-057:
customer_putdeixou de dar 500 e ganhou guard de admin). Ver "Aviso de segurança".
Resumo¶
A troca de senha de outro usuário é feita pelo PUT genérico de atualização, enviando o campo password em texto plano. O backend gera o hash automaticamente (argon2 via passlib, validator password_hash nas entidades Admin/Customer) ao salvar. Não é necessário enviar a senha atual.
| Alvo | Endpoint | Payload schema |
|---|---|---|
| Usuário admin (painel) | PUT /api/v1/users |
AdminUpdate |
| Cliente (customer) | PUT /api/v1/customers |
CustomerUpdate |
Base URL: https://fdplay-api.infraifd.com
Pré-requisito de autorização¶
Pós DEBT-057, as rotas de cliente têm dupla trava: checagem users_type (em get_current_user) E guard de admin (_require_admin: exige user_type=='admin' no banco).
Acesso efetivo:
| Sessão | PUT /api/v1/customers (cliente) |
PUT /api/v1/users (admin) |
|---|---|---|
root |
✅ (recomendado) | ✅ |
Admin c/ perfil users-type incluindo customer_put / user_put e user_type=='admin' |
✅ | ✅ |
Operador c/ perfil padrão Admin (ADR-061) |
❌ HTTP 401 | ❌ HTTP 401 |
| Customer / não-admin | ❌ 401/403 | ❌ 401/403 |
Perfil Admin não basta
O perfil padrão Admin (ADR-061) não concede customer_put/user_put. Para esta tela, exija sessão root (caminho recomendado) ou um perfil customizado que conceda explicitamente a função e cujo portador seja user_type=='admin'.
Contrato da requisição¶
- Método:
PUT - Headers:
Authorization: Bearer <token>+Content-Type: application/json - Identificação do alvo: query param
?_id=<OBJECT_ID>ou campo_iddentro do objeto. - Body: uma lista (array) de objetos. Enviar apenas
password— a atualização é parcial (campos omitidos são preservados).
PUT /api/v1/users?_id=6a0a111650de0df77fde2a57
Authorization: Bearer <root_token>
Content-Type: application/json
[{ "password": "NovaSenhaSegura123" }]
Para cliente, troque a rota:
Regras que o front-end DEVE aplicar¶
- Mínimo 8 caracteres. Validar no cliente antes de enviar (senha curta → HTTP 422).
- Enviar somente
password. Não reenviarusername,email,nameetc. no mesmo PUT.- Em
customers, enviaremailno PUT é bloqueado (HTTP 400 — ADR-033). Email muda por fluxo próprio.
- Em
- Nunca exibir nem reutilizar o
passwordda resposta. A resposta devolve o documento compasswordjá como hash argon2. Reenviar esse hash num PUT futuro faz o backend tratá-lo como senha já criptografada (não re-hasheia). Tratarpasswordcomo write-only. - Confirmação explícita na UI. O backend não exige senha atual e não registra auditoria. Compensar no front: diálogo de confirmação ("Redefinir senha de
<nome>?") e log local de quem acionou. - Após sucesso, não manter a nova senha em memória/estado; limpar o campo.
Resposta de sucesso (200)¶
Retorna o(s) documento(s) atualizado(s) (formato GetDocsResponse200, lista em docs). O front-end só precisa confirmar status 200 e descartar o corpo (não renderizar password).
Tratamento de erros¶
| HTTP | Causa | Ação no front-end |
|---|---|---|
| 422 | Senha < 8 chars | Validar antes; erro de formulário |
| 401 | Sessão sem a permissão users_type (customer_put/user_put) |
"Sessão sem permissão. Use uma conta root." |
| 403 | _require_admin (não é admin/root) ou token inválido/expirado |
Forçar re-login / usar conta admin/root |
| 400 | (customers) email enviado junto no PUT |
Não enviar email; corrigir payload |
| 500 | _id inexistente / erro interno (controller encapsula exceções) |
Mensagem genérica; logar; revalidar o _id |
Limitação conhecida
O 500 estrutural de customer_put (instanciava Admin para customer) foi corrigido em DEBT-057 (2026-05-18). Ainda assim, _id inexistente pode retornar 500 (não 404) — o controller genérico (ManageData) encapsula exceções. Garanta que o _id venha de um item realmente listado.
Exemplo (Dart / Dio)¶
Future<void> resetUserPassword({
required String userId,
required String newPassword,
bool isCustomer = false,
}) async {
assert(newPassword.length >= 8); // validar antes (evita 422)
final path = isCustomer ? '/api/v1/customers' : '/api/v1/users';
await dio.put(
path,
queryParameters: {'_id': userId},
data: [
{'password': newPassword}, // SOMENTE password; corpo é uma lista (array)
],
options: Options(headers: {'Authorization': 'Bearer $rootToken'}),
);
// Sucesso: não armazenar/loggar newPassword; limpar o campo do form.
}
Aviso de segurança¶
Dívida de Governança
Este caminho não gera log de auditoria (diferente das ações ADMIN.CUSTOMER.*) e não exige a senha atual. É mecanismo interino via CRUD genérico, não endpoint projetado. Follow-up recomendado: endpoint dedicado auditado (POST /admin/customers/{id}/reset-password com reason, padrão ADR-048). Até lá, a rastreabilidade depende de o painel logar quem acionou e por quê.
Referências¶
- ADR-061 — RBAC por nome-de-função + perfis padrão
users-type - ADR-048 — Admin Customer Management (padrão de audit log)
- ADR-033 — Re-verificação de email na alteração (bloqueio de
emailno PUT de customer) - ADR-057 — Serialização BSON-aware para insert/update