162 lines
6.3 KiB
Python
162 lines
6.3 KiB
Python
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__)
|
|
CORS(app) # Habilita CORS para todas as rotas
|
|
|
|
# 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({'msg': 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]
|
|
|
|
# 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'))
|