feat rbac com adicionados os novos campos para hierarquia

This commit is contained in:
LS
2025-04-01 15:27:16 -03:00
parent 01f5901eb2
commit 449a203926
3 changed files with 212 additions and 7 deletions

View File

@@ -6,6 +6,10 @@ import pyotp
import os
from pathlib import Path
from sqlalchemy.pool import NullPool
from datetime import datetime, timedelta
import secrets
from flask_mail import Message
from flask import url_for
# Configurar caminho do banco de dados
db_dir = Path.home() / '.local' / 'share' / 'controles'
@@ -46,6 +50,27 @@ def execute_query(query, params=None):
finally:
session.close()
class Celula(Base):
__tablename__ = 'celulas'
id = Column(Integer, primary_key=True, autoincrement=True)
nome = Column(String(100), nullable=False)
setor_id = Column(Integer, ForeignKey('setores.id'))
cr_id = Column(Integer, ForeignKey('comites_regionais.id'))
setor = relationship("Setor", back_populates="celulas")
cr = relationship("ComiteRegional", back_populates="celulas")
militantes = relationship("Militante", back_populates="celula")
class ComiteRegional(Base):
__tablename__ = 'comites_regionais'
id = Column(Integer, primary_key=True, autoincrement=True)
nome = Column(String(100), nullable=False)
setores = relationship("Setor", back_populates="cr")
celulas = relationship("Celula", back_populates="cr")
class Militante(Base):
__tablename__ = 'militantes'
@@ -56,12 +81,93 @@ class Militante(Base):
telefone = Column(String(15))
endereco = Column(String(255))
filiado = Column(Boolean, default=False)
celula_id = Column(Integer, ForeignKey('celulas.id'))
responsabilidades = Column(Integer, default=0) # Armazenará as responsabilidades como bits
otp_secret = Column(String(32))
temp_token = Column(String(64))
temp_token_expiry = Column(DateTime)
cotas_mensais = relationship("CotaMensal", back_populates="militante")
pagamentos = relationship("Pagamento", back_populates="militante")
materiais_vendidos = relationship("MaterialVendido", back_populates="militante")
vendas_jornais = relationship("VendaJornalAvulso", back_populates="militante")
assinaturas = relationship("AssinaturaAnual", back_populates="militante")
celula = relationship("Celula", back_populates="militantes")
# Constantes para responsabilidades
SECRETARIO = 1
TESOUREIRO = 2
IMPRENSA = 4
MNS = 8
MPS = 16
JUVENTUDE = 32
@staticmethod
def get_responsabilidades_list():
return [
(Militante.SECRETARIO, "Secretário"),
(Militante.TESOUREIRO, "Tesoureiro"),
(Militante.IMPRENSA, "Imprensa"),
(Militante.MNS, "MNS"),
(Militante.MPS, "MPS"),
(Militante.JUVENTUDE, "Juventude")
]
def set_responsabilidades(self, resp_list):
"""
Define as responsabilidades do militante
resp_list: lista de inteiros representando as responsabilidades
"""
self.responsabilidades = sum(resp_list)
def get_responsabilidades(self):
"""
Retorna lista de responsabilidades ativas
"""
resp = []
for valor, nome in self.get_responsabilidades_list():
if self.responsabilidades & valor:
resp.append(nome)
return resp
def generate_temp_token(self):
"""
Gera um token temporário para acesso ao QR code
"""
self.temp_token = secrets.token_urlsafe(32)
self.temp_token_expiry = datetime.now() + timedelta(hours=48)
return self.temp_token
def send_otp_email(self, mail):
"""
Envia email com link para QR code
"""
token = self.generate_temp_token()
qr_url = url_for('get_qr_code', token=token, _external=True)
msg = Message(
'Configuração de Autenticação em Duas Etapas',
recipients=[self.email]
)
msg.body = f"""
Olá {self.nome},
Para configurar sua autenticação em duas etapas, acesse o link abaixo:
{qr_url}
Este link expirará em 48 horas.
Instruções:
1. Instale um aplicativo autenticador (Google Authenticator, Microsoft Authenticator)
2. Acesse o link acima
3. Escaneie o QR code com o aplicativo
4. Use o código gerado para fazer login no sistema
Atenciosamente,
Sistema de Controles
"""
mail.send(msg)
class CotaMensal(Base):
__tablename__ = 'cotas_mensais'
@@ -150,6 +256,7 @@ class Setor(Base):
relatorios_cotas = relationship("RelatorioCotasMensais", back_populates="setor")
relatorios_vendas = relationship("RelatorioVendasMateriais", back_populates="setor")
usuarios = relationship("Usuario", back_populates="setor")
celulas = relationship("Celula", back_populates="setor")
class ComiteCentral(Base):
__tablename__ = 'comites_centrais'