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

74
app.py
View File

@@ -14,6 +14,7 @@ from functions.database import (
RelatorioVendasMateriais,
Usuario,
get_db_connection,
ComiteRegional,
)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
@@ -25,6 +26,7 @@ from functools import wraps
from pathlib import Path
from time import time
from create_admin import generate_qr_code
from flask_mail import Mail, Message
app = Flask(__name__)
app.secret_key = 'sua_chave_secreta_aqui' # Necessário para sessões do Flask
@@ -33,6 +35,15 @@ bootstrap = Bootstrap5(app)
# Configuração da sessão do SQLAlchemy
db_session = get_db_connection()
# Configurar Flask-Mail
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'seu-email@gmail.com'
app.config['MAIL_PASSWORD'] = 'sua-senha'
mail = Mail(app)
# Decorator para verificar se o usuário está logado
def login_required(f):
@wraps(f)
@@ -181,36 +192,74 @@ def home():
@login_required
@session_timeout
def novo_militante():
# Obter células disponíveis baseado no nível do usuário
user = db_session.query(Usuario).get(session['user_id'])
celulas_disponiveis = []
if user.role.nivel == 1: # CC
celulas_por_cr = db_session.query(ComiteRegional).all()
elif user.role.nivel == 2: # CR
celulas_por_cr = [user.cr]
elif user.role.nivel == 3: # Setor
celulas_por_cr = [{
'nome': user.setor.cr.nome,
'setores': [user.setor]
}]
else: # Célula
celulas_por_cr = [{
'nome': user.celula.setor.cr.nome,
'setores': [{
'nome': user.celula.setor.nome,
'celulas': [user.celula]
}]
}]
if request.method == "POST":
cpf = request.form["cpf"]
if not validar_cpf(cpf):
flash('CPF inválido. Por favor, verifique o número informado.', 'error')
return render_template("novo_militante.html",
dados_anteriores=request.form)
dados_anteriores=request.form,
responsabilidades=Militante.get_responsabilidades_list(),
celulas_por_cr=celulas_por_cr)
# Criar militante
novo_militante = Militante(
nome=request.form["nome"],
cpf=cpf,
email=request.form["email"],
telefone=request.form["telefone"],
endereco=request.form["endereco"],
filiado=bool(request.form.get("filiado", False))
filiado=bool(request.form.get("filiado", False)),
celula_id=request.form["celula_id"]
)
# Definir responsabilidades
responsabilidades = [
int(r) for r in request.form.getlist("responsabilidades")
]
novo_militante.set_responsabilidades(responsabilidades)
db_session.add(novo_militante)
try:
db_session.commit()
flash('Militante cadastrado com sucesso!', 'success')
# Enviar email com QR code
novo_militante.send_otp_email(mail)
flash('Militante cadastrado com sucesso! Um email foi enviado com as instruções de autenticação.', 'success')
return redirect(url_for("listar_militantes"))
except Exception as e:
print(e)
db_session.rollback()
flash('Erro ao cadastrar militante. Verifique se o CPF ou email já não estão cadastrados.', 'error')
flash('Erro ao cadastrar militante.', 'error')
return render_template("novo_militante.html",
dados_anteriores=request.form)
dados_anteriores=request.form,
responsabilidades=Militante.get_responsabilidades_list(),
celulas_por_cr=celulas_por_cr)
return render_template("novo_militante.html")
return render_template("novo_militante.html",
responsabilidades=Militante.get_responsabilidades_list(),
celulas_por_cr=celulas_por_cr)
# Rota para listar militantes
@app.route("/militantes")
@@ -567,6 +616,17 @@ def check_session():
return jsonify({'expired': False})
@app.route("/qr/<token>")
def get_qr_code(token):
militante = db_session.query(Militante).filter_by(temp_token=token).first()
if not militante or militante.temp_token_expiry < datetime.now():
flash('Link expirado ou inválido', 'error')
return redirect(url_for('login'))
qr_path = generate_qr_code(militante)
return render_template('mostrar_qr_code.html', qr_uri=militante.get_otp_uri())
def create_app():
app = Flask(__name__)
# ... existing code ...