feat rbac com adicionados os novos campos para hierarquia
This commit is contained in:
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user