From 6a3675b735a091e5d83430e80855483acdeeec9f Mon Sep 17 00:00:00 2001 From: LS Date: Tue, 22 Apr 2025 18:13:24 -0300 Subject: [PATCH] rebase usando pagamentos --- app.py | 275 +++++++++++++++++++++++++++++++++ templates/base.html | 4 + templates/dashboard_admin.html | 10 +- 3 files changed, 288 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index 11b5b6e..66517e3 100644 --- a/app.py +++ b/app.py @@ -1896,6 +1896,151 @@ def create_app(): db.close() return render_template('comprovantes/form.html') + @app.route("/alterar_senha", methods=["GET", "POST"]) + @require_login + def alterar_senha(): + """Rota para alterar a senha do usuário""" + if request.method == "POST": + senha_atual = request.form.get("senha_atual") + nova_senha = request.form.get("nova_senha") + confirmar_senha = request.form.get("confirmar_senha") + + if not all([senha_atual, nova_senha, confirmar_senha]): + flash("Todos os campos são obrigatórios.", "error") + return redirect(url_for("alterar_senha")) + + if nova_senha != confirmar_senha: + flash("As senhas não coincidem.", "error") + return redirect(url_for("alterar_senha")) + + db = get_db_connection() + try: + user = db.query(Usuario).get(current_user.id) + if not user.check_password(senha_atual): + flash("Senha atual incorreta.", "error") + return redirect(url_for("alterar_senha")) + + user.password_hash = generate_password_hash(nova_senha) + db.commit() + flash("Senha alterada com sucesso!", "success") + return redirect(url_for("home")) + finally: + db.close() + + return render_template("alterar_senha.html") + + @app.route('/usuarios//toggle_status', methods=['POST']) + @require_login + def toggle_user_status(user_id): + if not current_user.is_admin: + return jsonify({ + 'success': False, + 'error': 'Você não tem permissão para alterar o status de usuários.' + }), 403 + + db = get_db_connection() + try: + usuario = db.query(Usuario).get(user_id) + if not usuario: + return jsonify({ + 'success': False, + 'error': 'Usuário não encontrado.' + }), 404 + + usuario.ativo = not usuario.ativo + db.commit() + + return jsonify({ + 'success': True, + 'message': f'Usuário {"ativado" if usuario.ativo else "desativado"} com sucesso!' + }) + except Exception as e: + db.rollback() + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 + finally: + db.close() + + @app.route('/usuarios//alterar_nivel', methods=['POST']) + @require_login + def alterar_nivel(user_id): + user = db_session.query(Usuario).get_or_404(user_id) + novo_nivel = request.json.get('nivel') + + # Verificar permissões baseado na hierarquia + if not current_user.has_permission('system_config'): + if current_user.has_permission('manage_cr_sectors'): + # Secretário de CR só pode alterar níveis dentro do seu CR + if user.cr_id != current_user.cr_id: + return jsonify({'success': False, 'message': 'Você não tem permissão para alterar o nível deste usuário.'}) + elif current_user.has_permission('manage_sector_cells'): + # Secretário de Setor só pode alterar níveis dentro do seu setor + if user.setor_id != current_user.setor_id: + return jsonify({'success': False, 'message': 'Você não tem permissão para alterar o nível deste usuário.'}) + else: + # Outros níveis não podem alterar níveis + return jsonify({'success': False, 'message': 'Você não tem permissão para alterar níveis de usuários.'}) + + # Verificar se o novo nível é válido para o nível hierárquico do usuário atual + if current_user.has_permission('system_config'): + # Secretário Geral e Secretário de Organização podem alterar para qualquer nível + pass + elif current_user.has_permission('manage_cr_sectors'): + # Secretário de CR só pode alterar para níveis do CR + if novo_nivel not in ['membro_cr', 'secretario_cr']: + return jsonify({'success': False, 'message': 'Nível inválido para este CR.'}) + elif current_user.has_permission('manage_sector_cells'): + # Secretário de Setor só pode alterar para níveis do setor + if novo_nivel not in ['membro_setor', 'secretario_setor']: + return jsonify({'success': False, 'message': 'Nível inválido para este setor.'}) + + # Atualizar o nível do usuário + user.role = novo_nivel + db_session.commit() + + return jsonify({'success': True, 'message': 'Nível do usuário alterado com sucesso!'}) + + @app.route('/usuarios//toggle_quadro_orientador', methods=['POST']) + @require_login + def toggle_quadro_orientador(user_id): + db = get_db_connection() + try: + user = db.query(Usuario).get(user_id) + if not user: + return jsonify({'success': False, 'message': 'Usuário não encontrado'}), 404 + + # Verificar permissões + if not (current_user.has_permission('system_config') or + (current_user.has_permission('manage_cr_sectors') and user.cr_id == current_user.cr_id) or + (current_user.has_permission('manage_sector_cells') and user.setor_id == current_user.setor_id)): + return jsonify({'success': False, 'message': 'Você não tem permissão para alterar esta responsabilidade'}), 403 + + # Verificar se o usuário tem um militante associado + if not user.militante: + return jsonify({'success': False, 'message': 'Usuário não tem um militante associado'}), 400 + + # Alternar o status de Quadro-Orientador + user.militante.quadro_orientador = not user.militante.quadro_orientador + + # Atualizar a responsabilidade no campo responsabilidades + if user.militante.quadro_orientador: + user.militante.responsabilidades |= Militante.QUADRO_ORIENTADOR + else: + user.militante.responsabilidades &= ~Militante.QUADRO_ORIENTADOR + + db.commit() + return jsonify({ + 'success': True, + 'message': f'Responsabilidade de Quadro-Orientador {"adicionada" if user.militante.quadro_orientador else "removida"} com sucesso' + }) + except Exception as e: + db.rollback() + return jsonify({'success': False, 'message': str(e)}), 500 + finally: + db.close() + @app.route('/dashboard') @login_required def dashboard(): @@ -2139,6 +2284,136 @@ def create_app(): campanhas = db.query(CampanhaFinanceira).all() return render_template("listar_campanhas_financeira.html", campanhas=campanhas) + @app.route('/dashboard_admin') + @login_required + def dashboard_admin(): + """Rota para o dashboard administrativo""" + if not current_user.is_admin: + flash('Você não tem permissão para acessar esta página.', 'danger') + return redirect(url_for('home')) + + db = get_db_connection() + try: + # Busca usuários + usuarios = db.query(Usuario).all() + + usuarios_data = [] + for usuario in usuarios: + user_data = { + 'id': usuario.id, + 'username': usuario.username, + 'email': usuario.email, + 'nome': usuario.username, # Usar username como fallback + 'ativo': usuario.ativo, + 'is_admin': usuario.is_admin, + 'last_login': usuario.ultimo_login.strftime('%d/%m/%Y %H:%M') if usuario.ultimo_login else 'Nunca', + 'nivel': 'Administrador' if usuario.is_admin else 'Usuário' + } + usuarios_data.append(user_data) + + return render_template( + 'dashboard_admin.html', + usuarios=usuarios_data + ) + except Exception as e: + import traceback + print(f"Erro no dashboard_admin: {traceback.format_exc()}") + flash('Erro ao carregar dados dos usuários. Por favor, tente novamente.', 'danger') + return redirect(url_for('home')) + finally: + db.close() + + @app.route('/reset_otp/', methods=['POST']) + @login_required + def reset_otp(user_id): + if not current_user.is_admin: + return jsonify({ + 'success': False, + 'error': 'Você não tem permissão para resetar OTP.' + }), 403 + + db = get_db_connection() + try: + usuario = db.query(Usuario).get(user_id) + if not usuario: + return jsonify({ + 'success': False, + 'error': 'Usuário não encontrado.' + }), 404 + + usuario.otp_secret = pyotp.random_base32() + db.commit() + + return jsonify({ + 'success': True + }) + except Exception as e: + db.rollback() + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 + finally: + db.close() + + @app.route('/reset_password/', methods=['POST']) + @login_required + def reset_password(user_id): + if not current_user.is_admin: + return jsonify({ + 'success': False, + 'error': 'Você não tem permissão para resetar senhas.' + }), 403 + + db = get_db_connection() + try: + usuario = db.query(Usuario).get(user_id) + if not usuario: + return jsonify({ + 'success': False, + 'error': 'Usuário não encontrado.' + }), 404 + + nova_senha = ''.join(random.choices(string.ascii_letters + string.digits, k=12)) + usuario.set_password(nova_senha) + + try: + msg = Message( + 'Nova Senha - Sistema de Controles', + recipients=[usuario.email] + ) + msg.body = f'''Olá {usuario.nome}, + +Sua senha foi resetada por um administrador. Sua nova senha é: + +{nova_senha} + +Por favor, altere esta senha no seu próximo login. + +Atenciosamente, +Sistema de Controles''' + + mail.send(msg) + except Exception as e: + print(f"Erro ao enviar email: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Erro ao enviar email com a nova senha.' + }), 500 + + db.commit() + return jsonify({ + 'success': True + }) + except Exception as e: + db.rollback() + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 + finally: + db.close() + return app def init_system(): diff --git a/templates/base.html b/templates/base.html index 778505d..a0fe3b0 100644 --- a/templates/base.html +++ b/templates/base.html @@ -600,7 +600,11 @@
  • +<<<<<<< HEAD +======= + +>>>>>>> 09b0d0e (fix: Correções na página de administração e suas dependências) Administração
  • diff --git a/templates/dashboard_admin.html b/templates/dashboard_admin.html index 01a549a..29cd69c 100644 --- a/templates/dashboard_admin.html +++ b/templates/dashboard_admin.html @@ -6,7 +6,14 @@

    Administração de Usuários

    +
    +

    Administração de Usuários

    +
    + +
    @@ -29,6 +36,7 @@ @@ -195,4 +203,4 @@ $(function () { $('[data-toggle="tooltip"]').tooltip(); }); -{% endblock %} \ No newline at end of file +{% endblock %}
    {{ usuario.last_login }} + {{ "Ativo" if usuario.ativo else "Inativo" }}