from flask import Flask, request, jsonify from flask_mysqldb import MySQL import ldap3 import re import os from dotenv import load_dotenv import jwt # Importa a biblioteca JWT para gerar e validar tokens from datetime import datetime, timedelta from ldap3.core.exceptions import LDAPSocketOpenError, LDAPException # Importa as exceções específicas de ldap3 from flask_cors import CORS from flask import Flask, request, jsonify, send_from_directory # Carregar variáveis de ambiente do arquivo .env load_dotenv() app = Flask(__name__) # Permitir apenas uma origem específica CORS(app, resources={r"/*": {"origins": "https://dev.itguys.com.br"}}) # Configuração do MySQL usando variáveis de ambiente app.config['MYSQL_HOST'] = os.getenv('MYSQL_HOST') app.config['MYSQL_USER'] = os.getenv('MYSQL_USER') app.config['MYSQL_PASSWORD'] = os.getenv('MYSQL_PASSWORD') app.config['MYSQL_DB'] = os.getenv('MYSQL_DB') # Configuração da chave secreta para JWT app.config['SECRET_KEY'] = os.getenv('JWT_SECRET') # Verifique se a chave secreta é uma string válida if not isinstance(app.config['SECRET_KEY'], str): raise ValueError("SECRET_KEY deve ser uma string válida.") mysql = MySQL(app) @app.route('/login', methods=['POST']) def login(): data = request.get_json() username_full = data.get('username') # Extrai o e-mail completo do usuário dos dados da requisição. password = data.get('password') # Extrai a senha dos dados da requisição. # Validação do formato do e-mail if not re.match(r"[^@]+@[^@]+\.[^@]+", username_full): return jsonify({'msg': 'Formato de e-mail inválido'}), 400 # Extrair o nome de usuário (parte antes do @) username = username_full.split('@')[0] # Separar o domínio domain = username_full.split('@')[1] # Verificar se o domínio existe na tabela empresa cur = mysql.connection.cursor() cur.execute("SELECT idempresa, ip_dominio FROM empresa WHERE dominio = %s", (domain,)) empresa_result = cur.fetchone() if empresa_result is None: # Verifica se o domínio não existe na tabela empresa. cur.close() return jsonify({'msg': 'Domínio não encontrado no banco de dados'}), 404 id_empresa, ip_dominio = empresa_result # Armazena o ID da empresa e o IP do domínio encontrados no banco de dados. # Verificar se o usuário está associado à empresa no MySQL usando a view cur.execute("SELECT empresa_id, dominio_empresa FROM view_usuario_empresa WHERE usuario = %s AND dominio_empresa = %s", (username, domain)) result = cur.fetchone() cur.close() if result is None: # Verifica se o usuário não está associado à empresa. return jsonify({'msg': 'Usuário não associado à empresa'}), 404 empresa_id, dominio_empresa = result # Conectar ao servidor LDAP correspondente e autenticar o usuário ldap_server = f'ldap://{ip_dominio}:389' try: # Configurar o servidor LDAP server = ldap3.Server(ldap_server) # Tentar criar a conexão conn = ldap3.Connection(server, user=username_full, password=password) # Tentar autenticar o usuário if conn.bind(): # Gerar o token JWT após autenticação bem-sucedida token = jwt.encode({ 'user': username_full, 'exp': datetime.utcnow() + timedelta(hours=1) # Token expira em 1 hora }, app.config['SECRET_KEY'], algorithm="HS256") return jsonify({'msg': 'Login bem-sucedido', 'token': token}), 200 else: return jsonify({'msg': 'Falha na autenticação LDAP'}), 401 except LDAPSocketOpenError: # Erro específico para problemas de conexão com o servidor LDAP return jsonify({'msg': 'Não foi possível conectar ao servidor LDAP. Verifique a conexão de rede e as configurações do servidor.'}), 503 except LDAPException as e: # Captura qualquer outra exceção LDAP genérica return jsonify({'Erro 500': f'Erro LDAP: {str(e)}'}), 500 # Decorador para proteger rotas com JWT def token_required(f): def wrapper(*args, **kwargs): token = request.headers.get('x-access-token') if not token: return jsonify({'msg': 'Token é necessário!'}), 401 try: # Decodifica o token para validar data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"]) except jwt.ExpiredSignatureError: # O token expirou return jsonify({'msg': 'Token expirado! Por favor, faça login novamente.'}), 401 except jwt.InvalidTokenError: # Token inválido por qualquer outro motivo return jsonify({'msg': 'Token inválido!'}), 401 return f(*args, **kwargs) return wrapper @app.route('/mounting', methods=['GET']) @token_required # Garante que o usuário esteja autenticado e o token JWT seja validado def mouting(): # Decodifica o token para obter o e-mail do usuário token = request.headers.get('x-access-token') data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"]) username_full = data['user'] # Extrair o domínio do email do usuário autenticado domain = username_full.split('@')[1] if not username_full: return jsonify({'msg': 'Token inválido!'}), 401 # Consultar o banco de dados para obter o nome da empresa com base no domínio cur = mysql.connection.cursor() cur.execute("SELECT nome FROM empresa WHERE dominio = %s", (domain,)) empresa_result = cur.fetchone() cur.close() if empresa_result is None: return jsonify({'msg': 'Empresa não encontrada no banco de dados para o domínio fornecido'}), 404 # Obtém o nome da empresa nome_empresa = empresa_result[0] # Definir o caminho do diretório onde os arquivos JSON estão armazenados json_directory = './json/' # Substitua pelo caminho real do diretório # Nome do arquivo JSON correspondente ao nome da empresa json_filename = f"{nome_empresa}.json" # Caminho completo para o arquivo JSON json_filepath = os.path.join(json_directory, json_filename) # Verificar se o arquivo JSON existe if not os.path.isfile(json_filepath): return jsonify({'msg': 'Arquivo JSON não encontrado para a empresa fornecida'}), 404 # Retornar o conteúdo do arquivo JSON return send_from_directory(json_directory, json_filename, as_attachment=False) if __name__ == '__main__': app.run(host="0.0.0.0", port=5000, ssl_context=('./fullchain1.pem','./privkey1.pem'))