Grupos e Permissões - Endpoints
Referência completa dos endpoints de grupos e sistema RBAC do Sinapse
Endpoints de Grupos e Permissões
O sistema de grupos e permissões (RBAC - Role-Based Access Control) do Sinapse permite gerenciar acessos de forma granular e escalável.
Conceitos Fundamentais
Hierarquia de Permissões
Usuário
├── Grupos (múltiplos)
│ └── Permissões do Grupo
└── Permissões Diretas
Permissões Efetivas = Grupos + Diretas + AdminGrupos Padrão
| Grupo | Descrição | Permissões Típicas |
|---|---|---|
admin | Administradores | Acesso total |
gestor | Gestores de equipe | Gerenciar usuários e recursos |
analista | Analistas de dados | Criar e analisar dados |
usuario | Usuário padrão | Acesso básico |
visualizador | Apenas leitura | Visualizar dados |
Listar Grupos
Lista todos os grupos disponíveis no sistema.
GET /api/v1/grupos
Authorization: Bearer {access_token}Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
page | integer | Número da página (padrão: 1) |
size | integer | Itens por página (padrão: 50) |
search | string | Buscar por nome ou descrição |
ativo | boolean | Filtrar por status |
sort | string | Campo para ordenação [Em breve] |
order | string | Direção: asc, desc [Em breve] |
Permissão necessária: grupos.listar
Success Response (200):
{
"total": 10,
"page": 1,
"size": 50,
"pages": 1,
"grupos": [
{
"id": 1,
"nome": "admin",
"descricao": "Administradores do sistema",
"ativo": true,
"criado_em": "2025-01-01T10:00:00-03:00",
"atualizado_em": "2025-07-29T14:30:00-03:00",
"total_usuarios": 5,
"permissoes": [
{
"id": 1,
"nome": "admin",
"descricao": "Acesso administrativo total"
}
]
},
{
"id": 2,
"nome": "gestor",
"descricao": "Gestores de equipe",
"ativo": true,
"total_usuarios": 20,
"permissoes": [
{
"id": 10,
"nome": "usuarios.listar",
"descricao": "Listar usuários"
},
{
"id": 11,
"nome": "usuarios.criar",
"descricao": "Criar usuários"
}
]
}
]
}Python - Listar Grupos com Detalhes:
import requests
def listar_grupos_detalhados(token):
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
"https://api.sinapse.org.br/v1/grupos",
headers=headers,
params={"size": 100}
)
if response.status_code == 200:
grupos = response.json()
print(f"Total de grupos: {grupos['total']}")
print("\nResumo de Grupos:")
print("-" * 60)
for grupo in grupos['items']:
print(f"\n{grupo['nome'].upper()}")
print(f" Descrição: {grupo['descricao']}")
print(f" Usuários: {grupo['usuarios_count']}")
print(f" Permissões: {grupo['permissoes_count']}")
if grupo['permissoes_count'] <= 5:
# Mostrar permissões se poucas
for perm in grupo['permissoes']:
print(f" - {perm['nome']}")
return grupos['items']JavaScript - Buscar Grupo Específico:
async function buscarGrupoPorNome(nome) {
const response = await fetch(
`/api/v1/grupos?nome=${encodeURIComponent(nome)}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (response.ok) {
const dados = await response.json();
return dados.items.find(g => g.nome === nome);
}
return null;
}
// Uso
const grupoAnalista = await buscarGrupoPorNome('analista');
console.log(`Grupo tem ${grupoAnalista.usuarios_count} usuários`);Criar Grupo
Cria um novo grupo no sistema.
POST /api/v1/grupos
Authorization: Bearer {access_token}
Content-Type: application/jsonBody Parameters:
{
"nome": "coordenadores",
"descricao": "Coordenadores regionais de saúde",
"ativo": true,
"permissoes_ids": [10, 11, 20, 21, 30]
}Validações:
- Nome único no sistema
- Nome deve ser lowercase, sem espaços
- Permissões devem existir
Permissão necessária: grupos.criar
Success Response (201):
{
"id": 6,
"nome": "coordenadores",
"descricao": "Coordenadores regionais de saúde",
"ativo": true,
"criado_em": "2025-07-29T15:00:00-03:00",
"permissoes": [
{
"id": 10,
"nome": "usuarios.listar"
},
{
"id": 11,
"nome": "usuarios.criar"
}
],
"mensagem": "Grupo criado com sucesso"
}Error Response (422):
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Dados inválidos",
"details": [
{
"field": "nome",
"message": "Grupo com este nome já existe"
},
{
"field": "permissoes_ids",
"message": "Permissões inválidas: [99, 100]"
}
]
}
}Criar Perfis de Acesso Customizados:
def criar_perfil_epidemiologista():
"""Cria grupo com permissões específicas para epidemiologistas"""
# Definir permissões necessárias
permissoes_epidemio = [
"agravos.listar",
"agravos.criar",
"agravos.editar",
"agravos.exportar",
"relatorios.gerar",
"relatorios.exportar",
"noticias.listar",
"dashboard.visualizar"
]
# Buscar IDs das permissões
permissoes_ids = []
for perm_nome in permissoes_epidemio:
perm = buscar_permissao_por_nome(perm_nome)
if perm:
permissoes_ids.append(perm['id'])
# Criar grupo
novo_grupo = {
"nome": "epidemiologista",
"descricao": "Profissionais de epidemiologia com acesso a dados de agravos",
"ativo": True,
"permissoes_ids": permissoes_ids
}
response = requests.post(
f"{base_url}/grupos",
headers=headers,
json=novo_grupo
)
if response.status_code == 201:
grupo = response.json()
print(f"Grupo '{grupo['nome']}' criado com {len(permissoes_ids)} permissões")
return grupo
else:
print(f"Erro ao criar grupo: {response.json()}")
return NoneAtualizar Grupo
Atualiza informações e permissões de um grupo.
PUT /api/v1/grupos/{id}
Authorization: Bearer {access_token}
Content-Type: application/jsonBody Parameters:
{
"descricao": "Coordenadores regionais e estaduais de saúde",
"ativo": true
}Campos especiais:
nome: Pode ser alterado (deve ser único)permissoes_ids: Atualiza todas as permissões do grupo
Permissão necessária: grupos.editar
Success Response (200):
{
"id": 6,
"message": "Grupo atualizado com sucesso",
"total_usuarios": 15
}Deletar Grupo
Remove um grupo do sistema.
DELETE /api/v1/grupos/{id}
Authorization: Bearer {access_token}Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
transferir_usuarios | integer | ID do grupo para transferir usuários [Em breve] |
force | boolean | Forçar exclusão mesmo com usuários [Em breve] |
Permissão necessária: grupos.deletar
Success Response (204):
Sem conteúdo
Nota: Atualmente, grupos com usuários não podem ser deletados.
Gerenciar Membros do Grupo
Adicionar Usuário ao Grupo
POST /api/v1/grupos/{grupo_id}/usuarios/{usuario_id}
Authorization: Bearer {access_token}Permissão: usuarios.gerenciar_permissoes
Remover Usuário do Grupo
DELETE /api/v1/grupos/{grupo_id}/usuarios/{usuario_id}
Authorization: Bearer {access_token}Listar Usuários do Grupo [Em breve]
GET /api/v1/grupos/{grupo_id}/usuarios
Authorization: Bearer {access_token}Adicionar Múltiplos Usuários
def adicionar_usuarios_em_lote(grupo_id, usuarios_ids):
"""Adiciona múltiplos usuários a um grupo"""
resultados = {
"sucesso": [],
"erros": []
}
for user_id in usuarios_ids:
try:
response = requests.post(
f"{base_url}/grupos/{grupo_id}/usuarios/{user_id}",
headers=headers
)
if response.status_code == 200:
resultados["sucesso"].append(user_id)
else:
resultados["erros"].append({
"user_id": user_id,
"erro": response.json().get("error", "Erro desconhecido")
})
except Exception as e:
resultados["erros"].append({
"user_id": user_id,
"erro": str(e)
})
print(f"Adicionados: {len(resultados['sucesso'])}")
print(f"Erros: {len(resultados['erros'])}")
return resultadosGerenciar Permissões do Grupo
Atualizar Permissões
Para atualizar as permissões de um grupo, use o endpoint PUT do grupo incluindo o campo permissoes_ids:
PUT /api/v1/grupos/{grupo_id}
Content-Type: application/json
{
"permissoes_ids": [10, 11, 12, 20, 21]
}Nota: Endpoints individuais para adicionar/remover permissões [Em breve].
Exemplo: Clonar Permissões
async function clonarPermissoes(grupoOrigemId, grupoDestinoId) {
// 1. Buscar permissões do grupo origem
const origem = await fetch(`/api/v1/grupos/${grupoOrigemId}`, {
headers: { 'Authorization': `Bearer ${token}` }
}).then(r => r.json());
const permissoesIds = origem.permissoes.map(p => p.id);
// 2. Aplicar ao grupo destino
const response = await fetch(
`/api/v1/grupos/${grupoDestinoId}/permissoes`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ permissoes_ids: permissoesIds })
}
);
if (response.ok) {
console.log(`${permissoesIds.length} permissões clonadas com sucesso`);
}
}Listar Permissões Disponíveis [Em breve]
Lista todas as permissões do sistema.
GET /api/v1/permissoes
Authorization: Bearer {access_token}Response:
{
"total": 50,
"categorias": {
"usuarios": [
{
"id": 10,
"nome": "usuarios.listar",
"descricao": "Visualizar lista de usuários",
"categoria": "usuarios"
},
{
"id": 11,
"nome": "usuarios.criar",
"descricao": "Criar novos usuários",
"categoria": "usuarios"
}
],
"agravos": [
{
"id": 20,
"nome": "agravos.listar",
"descricao": "Visualizar casos de agravos",
"categoria": "agravos"
}
]
}
}Casos de Uso Práticos
1. Criar Estrutura de Permissões Regional
def criar_estrutura_regional(estado, municipios):
"""Cria grupos para gestão regional de saúde"""
# 1. Criar grupo estadual
grupo_estado = criar_grupo({
"nome": f"gestor_{estado.lower()}",
"descricao": f"Gestores estaduais de {estado}",
"permissoes_ids": obter_permissoes_gestao_estadual()
})
# 2. Criar grupos municipais
grupos_municipios = []
for municipio in municipios:
grupo_mun = criar_grupo({
"nome": f"equipe_{municipio.lower().replace(' ', '_')}",
"descricao": f"Equipe de saúde de {municipio}",
"permissoes_ids": obter_permissoes_equipe_municipal()
})
grupos_municipios.append(grupo_mun)
# 3. Criar hierarquia (se suportado)
for grupo_mun in grupos_municipios:
vincular_grupo_superior(grupo_mun['id'], grupo_estado['id'])
return {
"estado": grupo_estado,
"municipios": grupos_municipios
}2. Auditoria de Permissões
async function auditarPermissoesGrupo(grupoId) {
const grupo = await fetch(`/api/v1/grupos/${grupoId}`, {
headers: { 'Authorization': `Bearer ${token}` }
}).then(r => r.json());
const usuarios = await fetch(`/api/v1/grupos/${grupoId}/usuarios`, {
headers: { 'Authorization': `Bearer ${token}` }
}).then(r => r.json());
// Análise de riscos
const permissoesAltoRisco = [
'usuarios.deletar',
'grupos.deletar',
'admin'
];
const riscos = grupo.permissoes
.filter(p => permissoesAltoRisco.includes(p.nome))
.map(p => ({
permissao: p.nome,
usuarios_afetados: usuarios.total
}));
if (riscos.length > 0) {
console.warn('Permissões de alto risco detectadas:');
console.table(riscos);
}
return {
grupo: grupo.nome,
total_usuarios: usuarios.total,
total_permissoes: grupo.permissoes.length,
riscos: riscos
};
}