Sistema de Controles OCI
Sistema web para gestão organizacional (militantes, estrutura hierárquica, cotas, pagamentos e materiais), com autenticação por senha + OTP, permissões RBAC e cache Redis.
🔧 Tecnologias
- Backend: Flask 3.0.2
- Frontend: Bootstrap 5, HTML5, CSS3, JavaScript
- Database: SQLite + SQLAlchemy 2.0+ (>= 2.0.36)
- Cache: Redis 7.4.4 (opcional fora do Docker)
- Authentication: Flask-Login + OTP (pyotp)
- Container: Docker + Docker Compose
- Server: Gunicorn
🚀 Status Atual
- Sistema com Arquitetura de Permissões (RBAC)
- Sistema de permissões implementado no nível de dados
- Estrutura organizacional completa
- Aplicação Flask rodando com Docker
- Redis cache integrado e funcionando
- Banco de dados SQLite inicializado
- Usuário admin configurado com OTP
- 30 militantes de teste criados
- Menus sempre visíveis, controle transparente
🏗️ Arquitetura de Permissões
O sistema implementa uma estratégia de controle de permissões no nível de dados, garantindo que:
- Menus permanecem sempre visíveis - Não há restrições na interface
- Dados são filtrados por hierarquia - Admin → CC → CR → Setor → Célula
- Templates nunca quebram - Sempre renderizam, mesmo com dados vazios
⚙️ Instalação - Pré-requisitos
- Docker + Docker Compose (para fluxo com containers)
- Porta 5000 disponível para a aplicação
- Porta 6379 disponível para Redis
- Python 3.10+ (recomendado)
pipmake
🐳 Primeiro Inicio com Docker (recomendado)
0. Clone o repositorio
git clone git@gitea.comunatec.org:comunatec/controles.git
cd controles
1. Resete o banco
make docker-db-reset
2. Adicione dados fakes para testes (opcional)
make docker-db-seed-fake
3. Subir aplicação
make dev-up
4. Acompanhar logs
- Aplicação:
logs/controles.log - Cache:
logs/cache.log - Docker:
docker-compose logs
make docker-logs # Toda a aplicação
docker-compose logs redis # Somente o redis
make cache-status # INFO do redis
5. Descer aplicação
make dev-down
🐍 Primeiro Inicio - Execução Local (Sem Docker)
0. Clone o repositorio
git clone git@gitea.comunatec.org:comunatec/controles.git
cd controles
1. Ambiente Python
python -m venv .venv
source .venv/bin/activate # Linux/Mac
# ou
venv\Scripts\activate # Windows
pip install -r requirements.txt
2. Crie o .env na raiz
Exemplo:
# Usando OTP padrão para não trocar toda hora no desenvolvimento
ADMIN_OTP_SECRET=JBSWY3DPEHPK3PXP
# Para usar o mesmo banco que o Docker (Linux/WSL permite bind-mount)
DATABASE_URL=sqlite:///data/database.db
REDIS_URL=redis://redis:6379/0
FLASK_APP=app.py
FLASK_ENV=development
SECRET_KEY=troque_esta_chave
APP_UID=1000
APP_GID=1000
MAIL_SERVER=seu_servidor_smtp
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=seu_email
MAIL_PASSWORD=sua_senha
Se Redis não estiver disponível localmente, a aplicação continua rodando sem cache.
3. Inicialize o banco e rode
make db-reset
make db-seed-fake # opcional
make run
# ou
make run-gunicorn # server de produção
🔐 Acesso ao Sistema
Credenciais do Admin
- URL: http://localhost:5000
- Usuário: admin
- Senha: admin123
- OTP Secret: JBSWY3DPEHPK3PXP
Configuração OTP
-
Instale um aplicativo autenticador (Google Authenticator, Microsoft Authenticator)
-
Configure manualmente:
- Descrição da chave (Codinome): Controles-OCI-admin
- Segredo OTP (Sua Chave): JBSWY3DPEHPK3PXP
- Tipo: TOTP
- Algoritmo: SHA1
- Dígitos: 6
- Intervalo: 30 segundos
OU use o QR Code gerado em /tmp/admin_qr.png ou /data/admin_qr.png ou admin_qr.png.
PS: Google Authenticator só tem "Codinome" e "Sua Chave" de config, e tá tudo bem.
Testes Automatizados
# ambiente já configurado
pip install -r tests/requirements-test.txt
pytest
Também existe run_tests.sh, que monta um venv e executa a suíte automaticamente.
- TODO: Talvez trocar o nome para venv_test
📁 Estrutura de arquivos
O sistema busca seguir padrão MVC (Model-View-Controller), atualmente está:
controles/
├── controllers/ # Controladores (lógica de rotas)
├── data/ # Banco de dados (e talvez qr_code admin)
├── docs/ # Documentações da arquitetura
├── functions/ # Funções utilitárias
├── logs/ # Logs de aplicação, redis...
├── migrations/ # Alterações de banco para não perder dados (produção)
├── models/ # Modelos (operações de banco)
├── routes/ # Rotas de aplicação
├── scripts/ # Scripts de gerenciamento
├── services/ # Serviços (lógica de negócio)
├── sql/ # Migrate para o rbac
├── static/ # Arquivos estáticos (icon/css/js)
├── templates/ # Views (templates HTML)
├── tests/ # Testes automatizados
├── utils/ # Funções sem regra de negócio ou dependencia de domínio
├── app.py # Ponto de entrada da aplicação
├── docker-compose.yml # Configuração Docker
├── Dockerfile # Imagem Docker
└── requirements.txt # Dependências Python
- TODO: temos duas rotas (routes e controllers)? Unificar futuramente.
- TODO: sql/migrate_db parece utilizar outro banco.
🤝 Contribuição
- Crie uma branch para sua feature
- Commit suas mudanças
- Push sua branch para o Gitea
- Outro camarada verifica a branch
- Abra um Pull Request para a branch solicitada
📄 Licença
Este projeto é privado para uso da OCI.
🔍 Troubleshooting
-
Redis não conecta
docker-compose logs redis docker-compose restart redis- Redis está indisponível localmente, mas app continua executando mesmo fora do Docker.
-
Cache não funciona
make cache-status make cache-clear -
Aplicação não inicia
docker-compose logs app docker-compose down && docker-compose up -d -
Modificações no banco local não alteram o banco no Docker
- Linux bind mount no grupo de usuario errado: ajuste
APP_UID/APP_GIDnoDockerfilepara seu grupo de usuarios (padrão=1000). - Docker com engine do Windows não consegue fazer bind mount, então alterações no banco local não refletem no banco do Docker, use as operações dentro do docker com make docker-* ou no windows instale o wsl2 e instale o Docker com apenas a engine "Docker no WSL".
- Linux bind mount no grupo de usuario errado: ajuste
Estrutura de Permissões (RBAC)
O sistema utiliza um sistema de controle de acesso baseado em papéis (RBAC), onde a verificação de ações são feitas com permissões (permission), e as permissões são pré-definidas com base em papeis (role). Que possuem a seguinte hierarquia:
Níveis de Papéis
-
Militante Básico (Nível 1)
- Visualizar próprios dados
- Editar próprios dados
- Visualizar dados da célula
-
Secretário de Célula (Nível 2)
- Todas as permissões do Militante Básico
- Gerenciar membros da célula
- Criar membros na célula
- Visualizar relatórios da célula
-
Membro de Setor (Nível 3)
- Todas as permissões do Secretário de Célula
- Visualizar relatórios do setor
-
Secretário de Setor (Nível 4)
- Todas as permissões do Membro de Setor
- Gerenciar células do setor
- Criar células no setor
-
Membro de CR (Nível 5)
- Todas as permissões do Secretário de Setor
- Visualizar relatórios do CR
-
Secretário de CR (Nível 6)
- Todas as permissões do Membro de CR
- Gerenciar setores do CR
- Criar setores no CR
-
Membro do CC (Nível 7)
- Todas as permissões do Secretário de CR
- Visualizar relatórios nacionais
-
Secretário Geral (Nível 8)
- Todas as permissões do Membro do CC
- Gerenciar CRs
- Criar CRs
- Configurar sistema
Uso do RBAC
Decoradores de Permissão
O sistema fornece três decoradores para controle de acesso:
-
@require_permission(permission_name)- Verifica se o usuário tem uma permissão específica
- Exemplo:
@require_permission('create_cell_member')
-
@require_role(role_name)- Verifica se o usuário tem um papel específico
- Exemplo:
@require_role('Secretário de Célula')
-
@require_minimum_role(min_level)- Verifica se o usuário tem um papel com nível mínimo
- Exemplo:
@require_minimum_role(Role.SECRETARIO_CR)
Verificando Permissões e Papéis no Código
# Verificar se um usuário tem uma permissão
if user.has_permission(Permission.CREATE_CELL_MEMBER):
# Faça algo
# Verificar se um usuário tem um papel
if user.has_role(Role.SECRETARIO_CELULA):
# Faça algo
# Obter o papel mais alto do usuário
highest_role = user.get_highest_role()
# Verificar se o usuário tem nível secretário de célula ou superior
if user.has_minimum_role(Role.SECRETARIO_CELULA):
# Faça algo
Documentação Complementar
- Documentação complementar:
docs/README.md - RBAC:
docs/rbac.md - Estratégia de permissões:
docs/permission_strategy.md - Redis e cache:
docs/redis_cache_setup.md - Histórico de correções de permissões:
docs/permission_fixes_summary.md
Segurança
- Todas as senhas são armazenadas com hash bcrypt
- Sessões expiram após período de inatividade
- Controle de acesso granular baseado em papéis
- Proteção contra CSRF
- Validação de entrada de dados