diff --git a/.env b/.env index a61055e..f9b995a 100644 --- a/.env +++ b/.env @@ -10,6 +10,7 @@ SMTP_PASSWORD=j5j@QaSB\Z4<)W]M|hOYbC\605zfGcv: SMTP_HOST=mail.itguys.com.br SMTP_PORT=465 SMTP_RECIPIENT=comercial@itguys.com.br + # Configurações LDAP (Windows AD) LDAP_SERVER=10.10.253.199/itguys.com.br LDAP_DOMAIN=itguys.com.br @@ -17,7 +18,21 @@ LDAP_BASE_DN=dc=itguys,dc=com,dc=br LDAP_USER=itguys\teste.dev LDAP_PASSWORD=123Mudar -ZAMMAD_API=http://10.10.253.59/api/v1/ +#API ZAMMAD +ZAMMAD_API= https://zammad.itguys.com.br/api/v1 ZAMMAD_USERNAME=teste.dev@itguys.com.br ZAMMAD_PASSWORD=123Mudar +ZAMMAD_TOKEN =QiFbQ7txT0BS_3N8GrwOzAS6f7ziVTa1VqcGGpaPFscvdcfnBVjgq699fFj6NpQW #Token expira em 2065 + +#API Inter +CLIENT_ID = bfedfb96-7caf-4310-8632-a924c5daa7e1 +CLIENT_SECRET = 502d577e-b324-4b93-9624-e6b082588dc5 +CERT_PATH = InterAPI_Certificado.crt +CERT_KEY_PATH = keyinter.pem + +#API ZABBIX +ZABBIX_URL = https://mimir.itguys.com.br/zabbix/api_jsonrpc.php +TOKEN_ZABBIX = 10925e9e452cade5270f4d930feb3b5e1aa2cc9b366c1c5b4d72996212b12c93 +ZABBIX_USER = vitoria.oliveira +ZABBIX_PASSWORD = 123Mudar \ No newline at end of file diff --git a/InterAPI_Certificado.crt b/InterAPI_Certificado.crt new file mode 100644 index 0000000..1a5b0f0 --- /dev/null +++ b/InterAPI_Certificado.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEljCCA36gAwIBAgIQJ18cUeVWL5QojTvvnDiLyTANBgkqhkiG9w0BAQsFADCB +ijELMAkGA1UEBhMCQlIxFTATBgNVBAgMDE1pbmFzIEdlcmFpczEXMBUGA1UEBwwO +QmVsbyBIb3Jpem9udGUxDDAKBgNVBAoMA0FQSTELMAkGA1UECwwCSVQxMDAuBgNV +BAMMJ0FQSSBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5CTAeFw0y +NTAxMjcxOTAyNTlaFw0yNjAxMjcyMDAyNTlaMIGrMQswCQYDVQQGEwJCUjELMAkG +A1UECBMCUkoxFzAVBgNVBAcTDlJJTyBERSBKQU5FSVJPMS0wKwYDVQQLEyRjMzI3 +NWVhZi04NDA2LTQzMDAtOTMzNC04OTRlZTRhMWYyOGIxDTALBgNVBAoTBG51bGwx +ODA2BgNVBAMTL1IgUk9DQU5DT1VSVCBDQVZBREFTIENPTlNVTFRPUklBIEVNIElO +Rk9STUFUSUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl8fvYOJe +kMJ1BH9m95lQO9zLEG153PZuoSBgEvCJ522tJlAPp1oo+SgC1LCSRLaDOxhlJbIo +0BIC5/ule6QmAMtaoC+qt+e8QzT8PKm7IX/SzpjziV7HNHKlEiNCeGC047iYTOWv +c843uUVicMBZfSJXodzE9RYIC4oTZnB83gvlaVk7xVyP4Auimg09F4dZTQjeI06T +RBgiPNJDn0+ilKWRUX2HGs0wnD2JX7wGPB+mkV0z5Rsv0F1D7IsIa3TdMsyBdzxX +0haz/bSB/R5ZxMTHZ3bzYoPWd5cSKenYu1FyFTKHebFhIFy2Vz6kbakVOgrWZDFx +yg8dzuTnKUzdWwIDAQABo4HUMIHRMAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUFBVp +/TT0EQj/WbtOGcyVlyKK4DwwHQYDVR0OBBYEFHQ+z6vbCts4TrDS5s+hIVHbh6rz +MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +VQYDVR0fBE4wTDBKoEigRoZEaHR0cDovL2NybC1hcGkuYmkubG9jYWwvY3JsLzE5 +MzY0ZTc2LWM0YmUtNDBiNi05YzcxLWEzYTdiNDA0NzRhNC5jcmwwDQYJKoZIhvcN +AQELBQADggEBAHbjYT794YA7W9KsX+uXQIxXvd5IBVt+xzQw787/PgQ3elJNS36R +Yq5FdFjdvYDXTyFEi2YS+egqW+4wdBIvMUcM+86HhuhcKbkAjeMu1yM6vcORuuTV +BJ47vbR3hQiABGYhzOeq00CazFcpnDgydxx0sIhzWsEYrKOozUcXqdPFxVCpeR0X +rzEJgyrJd1l6fI+X8z/n3BCqYfCk+OJ8HYgTT8wpAJBVynuRNJRjYTIU3yySyEal +Fyny4CZxltqbnS+gZedyJZYf9aEPxQKNXcdpqGdvnmLv62EuWU129Z97FJ9rWB39 +uFVdK6Uz+Klv+DqP3hDLatxqDsp30QrdwG0= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py index 2fb0a67..a7e5d49 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -9,6 +9,13 @@ from .routes.perfil import perfil from .routes.montagem import montagem from .routes.zabbix import zabbix from .routes.integrator import zammad +from.routes.boletos import boletos +from.routes.upload_img import imagem +from.routes.servicos import servicos +from.routes.empresas import empresas +from.routes.newuser import newuser +from.routes.integrazabbix import integra + # Inicializa o MySQL mysql = MySQL() @@ -33,7 +40,14 @@ def create_app(): app.register_blueprint(perfil) app.register_blueprint(montagem) app.register_blueprint(zabbix) + app.register_blueprint(integra) app.register_blueprint(zammad) + app.register_blueprint(boletos) + app.register_blueprint(imagem) + app.register_blueprint(servicos) + app.register_blueprint(empresas) + app.register_blueprint(newuser) + @app.route('/') def home(): diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc index 7fcb5cd..cf637b4 100644 Binary files a/app/__pycache__/__init__.cpython-311.pyc and b/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/app/__pycache__/config.cpython-311.pyc b/app/__pycache__/config.cpython-311.pyc index 3fe355b..f191cd2 100644 Binary files a/app/__pycache__/config.cpython-311.pyc and b/app/__pycache__/config.cpython-311.pyc differ diff --git a/app/config.py b/app/config.py index 23a6d81..d35bfc9 100644 --- a/app/config.py +++ b/app/config.py @@ -17,7 +17,7 @@ class Config: MYSQL_DB = os.getenv('MYSQL_DB', 'itguys') MYSQL_CURSORCLASS = 'DictCursor' - # Configurações do LDAP (Windows AD) + # Configurações do LDAP (Windows AD) LDAP_SERVER = os.getenv('LDAP_SERVER', 'ldap://itguys.com.br') # IP/Hostname do servidor LDAP LDAP_DOMAIN = os.getenv('LDAP_DOMAIN', 'itguys.com.br') # Domínio do AD (FQDN) LDAP_BASE_DN = os.getenv('LDAP_BASE_DN', 'dc=itguys,dc=com,dc=br') # Distinguished Name (DN) @@ -25,8 +25,14 @@ class Config: LDAP_PASSWORD = os.getenv('LDAP_PASSWORD', '123Mudar') # Senha do usuário LDAP #Api Zammad - zammad_api_url = 'http://zammad.itguys.com.br/api/v1' - zammad_token = 'L081vJ19kood2uDlTSSt59LWBaewT9-a-MH_VKno8RY' + zammad_api_url = os.getenv('zammad_api_url','http://zammad.itguys.com.br/api/v1') + zammad_token = os.getenv('zammad_token','L081vJ19kood2uDlTSSt59LWBaewT9-a-MH_VKno8RY') + #ID Inter + CLIENT_ID = os.getenv('CLIENT_ID',"bfedfb96-7caf-4310-8632-a924c5daa7e1") + CLIENT_SECRET = os.getenv ('CLIENT_SECRET',"502d577e-b324-4b93-9624-e6b082588dc5") + CERT_PATH = os.getenv('CERT_PATH',"InterAPI_Certificado.crt") + CERT_KEY_PATH = os.getenv('CERT_KEY_PATH',"keyinter.pem") + diff --git a/app/routes/__pycache__/auth.cpython-311.pyc b/app/routes/__pycache__/auth.cpython-311.pyc index a191178..dbc3c8c 100644 Binary files a/app/routes/__pycache__/auth.cpython-311.pyc and b/app/routes/__pycache__/auth.cpython-311.pyc differ diff --git a/app/routes/__pycache__/auth.cpython-312.pyc b/app/routes/__pycache__/auth.cpython-312.pyc new file mode 100644 index 0000000..dbea9ac Binary files /dev/null and b/app/routes/__pycache__/auth.cpython-312.pyc differ diff --git a/app/routes/__pycache__/boletos.cpython-311.pyc b/app/routes/__pycache__/boletos.cpython-311.pyc new file mode 100644 index 0000000..2141d67 Binary files /dev/null and b/app/routes/__pycache__/boletos.cpython-311.pyc differ diff --git a/app/routes/__pycache__/config.cpython-311.pyc b/app/routes/__pycache__/config.cpython-311.pyc index 8ce09bd..63e02ac 100644 Binary files a/app/routes/__pycache__/config.cpython-311.pyc and b/app/routes/__pycache__/config.cpython-311.pyc differ diff --git a/app/routes/__pycache__/config.cpython-312.pyc b/app/routes/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000..530fc4f Binary files /dev/null and b/app/routes/__pycache__/config.cpython-312.pyc differ diff --git a/app/routes/__pycache__/criar_boletos.cpython-311.pyc b/app/routes/__pycache__/criar_boletos.cpython-311.pyc new file mode 100644 index 0000000..100ea48 Binary files /dev/null and b/app/routes/__pycache__/criar_boletos.cpython-311.pyc differ diff --git a/app/routes/__pycache__/download.cpython-311.pyc b/app/routes/__pycache__/download.cpython-311.pyc new file mode 100644 index 0000000..0498e53 Binary files /dev/null and b/app/routes/__pycache__/download.cpython-311.pyc differ diff --git a/app/routes/__pycache__/download_boletos.cpython-311.pyc b/app/routes/__pycache__/download_boletos.cpython-311.pyc new file mode 100644 index 0000000..7d62078 Binary files /dev/null and b/app/routes/__pycache__/download_boletos.cpython-311.pyc differ diff --git a/app/routes/__pycache__/empresas.cpython-311.pyc b/app/routes/__pycache__/empresas.cpython-311.pyc new file mode 100644 index 0000000..8c96602 Binary files /dev/null and b/app/routes/__pycache__/empresas.cpython-311.pyc differ diff --git a/app/routes/__pycache__/imagem.cpython-311.pyc b/app/routes/__pycache__/imagem.cpython-311.pyc new file mode 100644 index 0000000..b92a960 Binary files /dev/null and b/app/routes/__pycache__/imagem.cpython-311.pyc differ diff --git a/app/routes/__pycache__/integrazabbix.cpython-311.pyc b/app/routes/__pycache__/integrazabbix.cpython-311.pyc new file mode 100644 index 0000000..7ccb6cc Binary files /dev/null and b/app/routes/__pycache__/integrazabbix.cpython-311.pyc differ diff --git a/app/routes/__pycache__/new_user.cpython-311.pyc b/app/routes/__pycache__/new_user.cpython-311.pyc new file mode 100644 index 0000000..dd794c3 Binary files /dev/null and b/app/routes/__pycache__/new_user.cpython-311.pyc differ diff --git a/app/routes/__pycache__/newuser.cpython-311.pyc b/app/routes/__pycache__/newuser.cpython-311.pyc new file mode 100644 index 0000000..0ce67f3 Binary files /dev/null and b/app/routes/__pycache__/newuser.cpython-311.pyc differ diff --git a/app/routes/__pycache__/newzabbix.cpython-311.pyc b/app/routes/__pycache__/newzabbix.cpython-311.pyc new file mode 100644 index 0000000..9ea4ad9 Binary files /dev/null and b/app/routes/__pycache__/newzabbix.cpython-311.pyc differ diff --git a/app/routes/__pycache__/servicos.cpython-311.pyc b/app/routes/__pycache__/servicos.cpython-311.pyc new file mode 100644 index 0000000..6d25ac5 Binary files /dev/null and b/app/routes/__pycache__/servicos.cpython-311.pyc differ diff --git a/app/routes/__pycache__/token.cpython-311.pyc b/app/routes/__pycache__/token.cpython-311.pyc new file mode 100644 index 0000000..7ee0ca2 Binary files /dev/null and b/app/routes/__pycache__/token.cpython-311.pyc differ diff --git a/app/routes/__pycache__/token.cpython-312.pyc b/app/routes/__pycache__/token.cpython-312.pyc new file mode 100644 index 0000000..6e0148e Binary files /dev/null and b/app/routes/__pycache__/token.cpython-312.pyc differ diff --git a/app/routes/__pycache__/upload_img.cpython-311.pyc b/app/routes/__pycache__/upload_img.cpython-311.pyc new file mode 100644 index 0000000..a544b6a Binary files /dev/null and b/app/routes/__pycache__/upload_img.cpython-311.pyc differ diff --git a/app/routes/__pycache__/visualizar_boletos.cpython-311.pyc b/app/routes/__pycache__/visualizar_boletos.cpython-311.pyc new file mode 100644 index 0000000..06849c0 Binary files /dev/null and b/app/routes/__pycache__/visualizar_boletos.cpython-311.pyc differ diff --git a/app/routes/__pycache__/zammad.cpython-311.pyc b/app/routes/__pycache__/zammad.cpython-311.pyc index cdfa48b..c7bb5b2 100644 Binary files a/app/routes/__pycache__/zammad.cpython-311.pyc and b/app/routes/__pycache__/zammad.cpython-311.pyc differ diff --git a/app/routes/auth.py b/app/routes/auth.py index 7f6750e..3f26225 100644 --- a/app/routes/auth.py +++ b/app/routes/auth.py @@ -5,8 +5,8 @@ import re import ldap3 from ldap3.core.exceptions import LDAPSocketOpenError, LDAPException from functools import wraps -from flask_mysqldb import MySQL import logging +from flask_mysqldb import MySQL # Configuração de logging para depuração logging.basicConfig(level=logging.DEBUG) @@ -14,7 +14,6 @@ logging.basicConfig(level=logging.DEBUG) auth = Blueprint('auth', __name__) mysql = MySQL() - # Decorador para validar o token JWT def token_required(f): @wraps(f) @@ -26,22 +25,7 @@ def token_required(f): try: data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=["HS256"]) except jwt.ExpiredSignatureError: - # Caso o token esteja expirado, gere um novo token - try: - # Obter o payload original para criar um novo token - payload = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=["HS256"], options={"verify_exp": False}) - - # Gere um novo token com nova validade - new_token = jwt.encode({ - 'user_id': payload['user_id'], - 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) - }, current_app.config['SECRET_KEY'], algorithm="HS256") - - response = jsonify({'msg': 'Token expirado! Novo token gerado.', 'new_token': new_token}) - response.status_code = 401 - return response - except Exception as e: - return jsonify({'msg': 'Erro ao processar o token expirado.', 'error': str(e)}), 401 + return jsonify({'msg': 'Token expirado!'}), 401 except jwt.InvalidTokenError: return jsonify({'msg': 'Token inválido!'}), 401 @@ -84,31 +68,20 @@ def login(): except ValueError: return jsonify({'msg': 'Formato de usuário inválido. Use "usuario@dominio.com".'}), 400 - # Buscar informações de domínio no banco de dados + # Verificar se o usuário está associado à empresa no MySQL try: - with mysql.connection.cursor() as cur: - cur.execute("SELECT idempresa, ip_dominio FROM empresa WHERE dominio = %s", (domain,)) - empresa_result = cur.fetchone() - - if not empresa_result: - return jsonify({'msg': 'Domínio não encontrado no banco de dados'}), 404 - - id_empresa, ip_dominio = empresa_result - - # Verificar se o usuário está associado à empresa no MySQL with mysql.connection.cursor() as cur: cur.execute("SELECT empresa_id, dominio FROM view_usuario_empresa WHERE usuario = %s AND dominio = %s", (username, domain)) result = cur.fetchone() if not result: return jsonify({'msg': 'Usuário não associado à empresa'}), 404 - except Exception as e: logging.error(f"Erro no banco de dados: {str(e)}") return jsonify({'msg': 'Erro no banco de dados'}), 500 - # Conexão LDAP com autenticação - ldap_server = f'ldap://{"itguys.com.br:389"}' + # Autenticação LDAP usando domínio extraído + ldap_server = f'ldap://{domain}:389' ldap_user = f'{domain}\\{username}' try: @@ -144,6 +117,3 @@ def login(): except Exception as e: logging.error(f"Erro inesperado: {str(e)}") return jsonify({'msg': 'Erro inesperado durante a autenticação.'}), 500 - - - diff --git a/app/routes/boletos.py b/app/routes/boletos.py new file mode 100644 index 0000000..e8ed4e4 --- /dev/null +++ b/app/routes/boletos.py @@ -0,0 +1,334 @@ +import os +import json +import requests +from time import time +from functools import wraps +from base64 import b64decode +from datetime import datetime, timedelta +from flask import Flask, Blueprint, jsonify, request, Response +from flask_mysqldb import MySQL +from flask_cors import CORS +from .auth import token_required +from dotenv import load_dotenv +from flask import send_file +import io + +load_dotenv() + +# Configurações da API do Banco Inter +CLIENT_ID = os.environ.get("CLIENT_ID") +CLIENT_SECRET = os.environ.get("CLIENT_SECRET") +CERT_PATH = os.environ.get("CERT_PATH") +CERT_KEY_PATH = os.environ.get("CERT_KEY_PATH") +ACCOUNT = os.environ.get("ACCOUNT", None) +API_BASE_URL = "https://cdpj.partners.bancointer.com.br" + +boletos = Blueprint('boletos', __name__) + +app = Flask(__name__) + +cors = CORS(app, resources={r"/v1/boletos/*": {"origins": "*", "methods": ["GET", "POST", "PUT", "OPTIONS"]}}) +app.config["CORS_HEADERS"] = ["Content-Type", "Authorization", "Content-Disposition", "Content-Length"] + +MYSQL_HOST = os.environ.get('MYSQL_HOST') +MYSQL_PORT = os.environ.get('MYSQL_PORT') +MYSQL_USER = os.environ.get('MYSQL_USER') +MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD') +MYSQL_DB = os.environ.get('MYSQL_DB') +MYSQL_CURSORCLASS = os.environ.get("MYSQL_CURSORCLASS") + +mysql = MySQL() +token_cache = {} + +def intercept_options(f): + @wraps(f) + def decorated(*args, **kwargs): + if request.method == "OPTIONS": + response = jsonify({"status": "ok"}) + response.headers.add("Access-Control-Allow-Origin", "*") + response.headers.add("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS") + response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization,Content-Disposition,Content-Length") + return response, 200 + return f(*args, **kwargs) + return decorated + + +def obter_token(scopes=["boleto-cobranca.write", "boleto-cobranca.read"]): + """Obtem um token de acesso para a API do Banco Inter.""" + scopes_param = " ".join(scopes) + if token_cache.get(scopes_param): + cached_token = token_cache.get(scopes_param) + # token is still valid + if cached_token.get("expires_at") > int(time()): + return cached_token["token"] + try: + request_string = f"client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&scope={scopes_param}&grant_type=client_credentials" + print("request_string", request_string) + response = requests.post(url=f"{API_BASE_URL}/oauth/v2/token", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + cert=(CERT_PATH, CERT_KEY_PATH), + data=request_string) + data_json = response.json() + token = data_json.get("access_token") + token_cache[scopes_param] = { + "token": token, + "expires_at": data_json.get("expires_in") + int(time()), + } + return token + except Exception as e: + print(f"Erro ao obter token de acesso: {e}") + return None + +def emitir_cobranca(token, dados_cobranca): + """Emite uma cobrança para o Banco Inter de forma assíncrona.""" + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json", + "Accept": "application/json" + } + try: + response = requests.post( + f"{API_BASE_URL}/cobranca/v3/cobrancas", + headers=headers, + cert=(CERT_PATH, CERT_KEY_PATH), + json=dados_cobranca + ) + + # Captura a resposta completa + resposta_json = response.json() + + # Exibe detalhes da resposta para debug + print("Código de status:", response.status_code) + print("Resposta da API:", json.dumps(resposta_json, indent=4, ensure_ascii=False)) + + return resposta_json + except Exception as e: + print(f"Erro ao emitir cobrança: {e}") + return None + +def obter_cobranca(token, codigo_solicitacao): + """Obtem uma cobrança.""" + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "Application/json", + } + try: + response = requests.get(f"{API_BASE_URL}/cobranca/v3/cobrancas/{codigo_solicitacao}", + headers=headers, + cert=(CERT_PATH, CERT_KEY_PATH)) + return response.json() + except Exception as e: + print(f"Erro ao emitir cobrança:{e}") + return None + +def obter_cobranca_pdf(token, codigo_solicitacao): + """Obtem o PDF de uma cobrança.""" + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "Application/json", + } + try: + # Certifique-se de que o codigo_solicitacao seja inserido corretamente na URL + url = f"{API_BASE_URL}/cobranca/v3/cobrancas/{codigo_solicitacao}/pdf" + response = requests.get(url, + headers=headers, + cert=(CERT_PATH, CERT_KEY_PATH)) + return response.json() + except Exception as e: + print(f"Erro ao emitir cobrança:{e}") + return None + +def processar_cobranca_cliente(cliente, token): + """ + Processa a emissão da cobrança para um cliente específico, + retornando os dados relevantes. + """ + id_empresa = cliente["idempresa"] + hoje = datetime.now() + vencimento = (hoje + timedelta(days=5)).strftime("%Y-%m-%d") + + dados_cobranca = { + "seuNumero": f"boleto-{id_empresa}", + "valorNominal": str(cliente["valor_servico"]), + "dataVencimento": vencimento, + "numDiasAgenda": 30, + "pagador": { + "cpfCnpj": cliente["cpf_cnpj"], + "tipoPessoa": cliente["tipo_pessoa"], + "nome": cliente["nome"], + "telefone": cliente["telefone"], + "endereco": cliente["endereco"], + "cidade": cliente["cidade"], + "uf": cliente["uf"], + "cep": cliente["cep"], + }, + "formasRecebimento": ["BOLETO", "PIX"], + } + + emissao_cobranca = emitir_cobranca(token, dados_cobranca) + codigo_solicitacao = emissao_cobranca.get("codigoSolicitacao") if emissao_cobranca else None + if not codigo_solicitacao: + return { + "cliente": cliente, + "status": "erro", + "mensagem": "Falha ao emitir cobrança." + } + + cobranca = obter_cobranca(token, codigo_solicitacao) + if not cobranca: + return { + "cliente": cliente, + "status": "erro", + "mensagem": "Falha ao obter cobrança." + } + + boleto_data = cobranca.get("cobranca", {}).get("boleto", {}) + codigo_barras = boleto_data.get("codigoBarras") + linha_digitavel = cobranca.get("boleto", {}).get("linhaDigitavel") + pix_data = cobranca.get("pix", {}) + pix_copia_e_cola = pix_data.get("pixCopiaECola") + + cobranca_pdf = obter_cobranca_pdf(token, codigo_solicitacao) + if not cobranca_pdf or "pdf" not in cobranca_pdf: + return { + "cliente": cliente, + "status": "erro", + "mensagem": "Falha ao obter PDF da cobrança." + } + + return { + "cliente": cliente, + "status": "sucesso", + "codigo_solicitacao": codigo_solicitacao, + "codigo_barras": codigo_barras, + "linha_digitavel": linha_digitavel, + "pix_copia_e_cola": pix_copia_e_cola, + "pdf": cobranca_pdf["pdf"], + } + + +@boletos.route('/', methods=['POST', 'OPTIONS']) +@intercept_options +@token_required +def gerar_boletos(data): + + domain = data.get('domain') + escopos = data.get('scopes', []) + escopos.append("boleto-cobranca.write") + escopos.append("boleto-cobranca.read") + print("data", data) + print(domain) + print(escopos) + if 'boleto-cobranca.write' not in escopos: + return jsonify({"erro": "Permissão necessária: boleto-cobranca.write"}), 403 + if not domain: + return jsonify({"error": "Domínio não encontrado no token"}), 400 + + hoje = datetime.now() + if hoje.day > 12: + return jsonify({"erro": "Boletos só podem ser gerados até o dia 12 de cada mês."}), 403 + + try: + cur = mysql.connection.cursor() + cur.execute( + "SELECT idempresa, nome, cpf_cnpj, tipo_pessoa, telefone, endereco, cidade, uf, cep, valor_servico FROM empresa WHERE dominio = %s", + (domain,) + ) + clientes = cur.fetchall() + cur.close() + if not clientes: + return jsonify({"erro": "Nenhum cliente encontrado."}), 404 + except Exception as e: + print(f"Erro ao acessar o banco de dados: {e}") + return jsonify({"erro": "Erro ao acessar o banco de dados."}), 500 + + token = obter_token(escopos) + if not token: + return jsonify({"erro": "Falha ao obter o token de acesso."}), 401 + + resultados = [] + for cliente in clientes: + resultado = processar_cobranca_cliente(cliente, token) + resultados.append(resultado) + + return jsonify({"resultados": resultados}), 200 + + +@boletos.route('/', methods=['GET', 'OPTIONS']) +@intercept_options +@token_required +def recuperar_cobranca(token_data, codigo_solicitacao): + print("codigo_solicitacao", codigo_solicitacao) + + scopes = token_data.get('scopes', []) + print("token_data", token_data) + + if 'boleto-cobranca.read' not in scopes: + return jsonify({"erro": "Permissao necessaria: boleto-cobranca.read"}), 403 + + token = obter_token(scopes) + if not token: + return jsonify({"erro": "Falha ao obter o token de acesso"}), 401 + + cobranca = obter_cobranca(token, codigo_solicitacao) + if cobranca is None: + return jsonify({"erro": "Erro ao obter PDF"}), 404 + + try: + codigo_barras = cobranca.get("boleto").get("codigoBarras") + linha_digitavel = cobranca.get("boleto").get("linhaDigitavel") + pix_copia_e_cola = cobranca.get("pix").get("pixCopiaECola") + + return jsonify({ + "codigo_solicitacao": codigo_solicitacao, + "codigo_barras": codigo_barras, + "linha_digitavel": linha_digitavel, + "pix_copia_e_cola": pix_copia_e_cola, + }), 200 + + except Exception as e: + return jsonify({"erro": f"Erro ao buscar cobranca: {e}"}), 500 + + +@boletos.route('//pdf', methods=['GET', 'OPTIONS']) +@intercept_options +@token_required +def recuperar_boleto(token_data, codigo_solicitacao): + print("codigo_solicitacao", codigo_solicitacao) + + scopes = token_data.get('scopes', []) + print("token_data", token_data) + + if 'boleto-cobranca.read' not in scopes: + return jsonify({"erro": "Permissao necessaria: boleto-cobranca.read"}), 403 + + token = obter_token(scopes) + if not token: + return jsonify({"erro": "Falha ao obter o token de acesso"}), 401 + + cobranca_pdf = obter_cobranca_pdf(token, codigo_solicitacao) + if cobranca_pdf is None: + return jsonify({"erro": "Erro ao obter PDF"}), 404 + + try: + pdf_content_base64 = cobranca_pdf["pdf"] + pdf_content_bytes = b64decode(pdf_content_base64, validate=True) + return Response(pdf_content_bytes, + mimetype='application/pdf', + headers={ + "Content-Disposition": "inline; filename=boleto.pdf", + "Content-Type": "application/pdf", + "Content-Length": len(pdf_content_bytes) + }) + except Exception as e: + return jsonify({"erro": f"Erro ao decodificar PDF: {e}"}), 500 + +if __name__ == "__main__": + app.register_blueprint(boletos) + app.run(port=5000, debug=True) + + + + + + diff --git a/app/routes/client.py b/app/routes/client.py new file mode 100644 index 0000000..7ccc766 --- /dev/null +++ b/app/routes/client.py @@ -0,0 +1,27 @@ +import os +import sys +import requests +from dotenv import load_dotenv +from flask import Blueprint + +load_dotenv() + +codigo_solicitacao = "" +API_BASE_URL = "https://dev.itguys.com.br" +url = f"{API_BASE_URL}/v1/boletos/{codigo_solicitacao}/pdf" +headers = { + "Authorization": "Bearer ", + "Content-Type": "application/json" +} +try: + response = requests.get(url, headers=headers) + if response.status_code != 200: + print("Erro obtendo o PDF") + sys.exit(1) + # salva o conteudo da resposta em um arquivo, pois ja retorna como bytes + with open(f"{codigo_solicitacao}-cobranca.pdf", "wb") as pdf_file: + pdf_file.write(response.content) + print(f"PDF salvo em {codigo_solicitacao}-cobranca.pdf") +except Exception as e: + print(e) + sys.exit(1) \ No newline at end of file diff --git a/app/routes/config.py b/app/routes/config.py index 267c19a..3341aa6 100644 --- a/app/routes/config.py +++ b/app/routes/config.py @@ -5,7 +5,7 @@ from dotenv import load_dotenv load_dotenv() class Config: - # Configurações Gerais + # Configurações Gerais SECRET_KEY = os.getenv('SECRET_KEY', 'd702717e2361ba1a31ce3b98d28ee3e24e2e6a9be8e2afd8e004f842563bacbd') DEBUG = os.getenv('DEBUG', 'True') == 'True' JSON_SORT_KEYS = False diff --git a/app/routes/empresas.py b/app/routes/empresas.py new file mode 100644 index 0000000..5e7ca6c --- /dev/null +++ b/app/routes/empresas.py @@ -0,0 +1,25 @@ +import logging +from flask import Blueprint, jsonify +from flask_mysqldb import MySQL +from .auth import token_required # Importando o token_required + + + +empresas = Blueprint('empresas', __name__) # Criando o Blueprint +mysql = MySQL() # Criando a instância do MySQL + +@empresas.route('/empresas', methods=['GET']) +@token_required +def listar_empresas(data): # Agora aceita o argumento 'data' + try: + cur = mysql.connection.cursor() + cur.execute("SELECT idempresa, nome, dominio FROM empresa") + resultados = cur.fetchall() + + # Ajuste aqui: Adicionando o 'id_empresa' no dicionário + empresas_list = [{"idempresa": row['idempresa'], "nome": row['nome'], "dominio": row['dominio']} for row in resultados] + + return jsonify(empresas_list), 200 + except Exception: + return jsonify({"erro": "Erro interno no servidor"}), 500 + diff --git a/app/routes/extrato.py b/app/routes/extrato.py new file mode 100644 index 0000000..d52c70e --- /dev/null +++ b/app/routes/extrato.py @@ -0,0 +1,124 @@ +import os +from time import time +from functools import wraps +from datetime import date +import requests +from dotenv import load_dotenv + +# Carregar variáveis de ambiente do arquivo .env +load_dotenv() + +# Definição das credenciais e URL base da API +CLIENT_ID = os.environ.get("CLIENT_ID") +CLIENT_SECRET = os.environ.get("CLIENT_SECRET") +CERT_PATH = os.environ.get("CERT_PATH") +CERT_KEY_PATH = os.environ.get("CERT_KEY_PATH") +ACCOUNT = os.environ.get("ACCOUNT", None) +API_BASE_URL = "https://cdpj.partners.bancointer.com.br" + +# Cache para tokens de acesso +token_cache = {} + +def token_required(f): + @wraps(f) + def decorated(*args, **kwargs): + data = { + "domain": "example.com", + "scopes": ["boleto-cobranca.write", "boleto-cobranca.read"] + } + return f(data, *args, **kwargs) + return decorated + +def obter_token(scopes=["boleto-cobranca.write", "boleto-cobranca.read"]): + """Obtem um token de acesso para a API do Banco Inter.""" + scopes_param = " ".join(scopes) + if token_cache.get(scopes_param): + cached_token = token_cache.get(scopes_param) + # token is still valid + if cached_token.get("expires_at") > int(time()): + return cached_token["token"] + try: + request_string = f"client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&scope={scopes_param}&grant_type=client_credentials" + print("request_string", request_string) + response = requests.post(url=f"{API_BASE_URL}/oauth/v2/token", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + cert=(CERT_PATH, CERT_KEY_PATH), + data=request_string) + + # Verificar o status da resposta + if response.status_code != 200: + print(f"Erro na requisição: {response.status_code}") + print("Resposta bruta:", response.text) # Imprime a resposta bruta para debugar + + data_json = response.json() + print("Resposta JSON:", data_json) # Imprimir o JSON da resposta + token = data_json.get("access_token") + + # Cache do token + token_cache[scopes_param] = { + "token": token, + "expires_at": data_json.get("expires_in") + int(time()), + } + return token + except Exception as e: + print(f"Erro ao obter token de acesso: {e}") + return None + + +def get_balance(): + """Obtém o saldo da conta no Banco Inter.""" + token = obter_token(["saldo.read"]) + if not token: + print("Erro: não foi possível obter o token de acesso.") + return None + + try: + response = requests.get( + f"{API_BASE_URL}/banking/v2/saldo", + headers={"Authorization": f"Bearer {token}"}, + cert=(CERT_PATH, CERT_KEY_PATH) + ) + response.raise_for_status() + return response.json() + + except requests.RequestException as e: + print(f"Erro ao obter saldo: {e}") + return None + + +def get_statements(start_date: str, end_date: str): + """Obtém o extrato da conta no Banco Inter entre as datas informadas.""" + token = obter_token(["extrato.read"]) + if not token: + print("Erro: não foi possível obter o token de acesso.") + return None + + try: + response = requests.get( + f"{API_BASE_URL}/banking/v2/extrato", + params={"dataInicio": start_date, "dataFim": end_date}, + headers={"Authorization": f"Bearer {token}"}, + cert=(CERT_PATH, CERT_KEY_PATH) + ) + response.raise_for_status() + return response.json() + + except requests.RequestException as e: + print(f"Erro ao obter extrato: {e}") + return None + + +if __name__ == "__main__": + time_now = time() + yesterday = date.fromtimestamp(time_now - 60 * 60 * 24).strftime("%Y-%m-%d") + today = date.fromtimestamp(time_now).strftime("%Y-%m-%d") + + print(f"Obtendo informações financeiras para o período: {yesterday} - {today}") + + # Obter saldo + balance_data = get_balance() + print("Saldo:", balance_data) + + # Obter extrato + statements_data = get_statements(yesterday, today) + print("Extrato:", statements_data) diff --git a/app/routes/integrazabbix.py b/app/routes/integrazabbix.py new file mode 100644 index 0000000..495b72d --- /dev/null +++ b/app/routes/integrazabbix.py @@ -0,0 +1,45 @@ +from flask import Blueprint, jsonify +from .auth import token_required # Importa o decorador de autenticação +from .newzabbix import zapi # Importa a conexão Zabbix + +integra = Blueprint('integra', __name__) + +def obter_dados_zabbix(): + try: + grupos = zapi.hostgroup.get(output="extend") + resultado = [] + + for grupo in grupos: + hosts = zapi.host.get(groupids=grupo['groupid'], output="extend") + hosts_info = [] + + for host in hosts: + itens = zapi.item.get(hostids=host['hostid'], output="extend", + filter={"key_": ["system.uptime", "net.if.in", "net.if.out", "vm.memory.size", "vfs.fs.size"]}) + + metricas = {item['key_']: item.get('lastvalue', 'N/A') for item in itens} + + packet_loss = zapi.item.get(hostids=host['hostid'], filter={"key_": "net.ping.loss"}, output="extend") + metricas["net.ping.loss"] = packet_loss[0]['lastvalue'] if packet_loss else 'N/A' + + hosts_info.append({ + "host_name": host['name'], + "metrics": metricas + }) + + resultado.append({ + "group_id": grupo['groupid'], + "group_name": grupo['name'], + "hosts": hosts_info + }) + + return resultado, 200 + + except Exception as e: + return {"error": "Erro ao buscar dados do Zabbix", "details": str(e)}, 500 + +@integra.route('/zabbix/hosts', methods=['GET']) +@token_required +def hosts_e_metricas(_): + dados, status_code = obter_dados_zabbix() + return jsonify(dados), status_code diff --git a/app/routes/newuser.py b/app/routes/newuser.py new file mode 100644 index 0000000..1e9013e --- /dev/null +++ b/app/routes/newuser.py @@ -0,0 +1,44 @@ +import logging +from flask import Blueprint, jsonify, request +from .auth import token_required +from flask_mysqldb import MySQL + +newuser = Blueprint('newuser', __name__) + +mysql = MySQL() + +# Configuração de logging +logging.basicConfig(level=logging.DEBUG) # Log no nível de debug + +@newuser.route('/inserir', methods=['POST']) +@token_required +def inserir_dados(get): # Recebe current_user do decorador + data = request.get_json() + + nome_completo = data.get('nome_completo') + usuario_ad = data.get('usuario_ad') + empresa = data.get('empresa') + dominio_empresa = data.get('dominio_empresa') + + if not nome_completo or not usuario_ad or not empresa or not dominio_empresa: + return jsonify({'erro': 'Todos os campos são obrigatórios'}), 400 + + conn = mysql.connection + cursor = conn.cursor() + + try: + query = """ + INSERT INTO usuarios (nome, usuario, empresa, dominio) + VALUES (%s, %s, %s, %s) + """ + cursor.execute(query, (nome_completo, usuario_ad, empresa, dominio_empresa)) + conn.commit() + + return jsonify({'message': 'Dados inseridos com sucesso!'}), 200 + + except Exception as err: + logging.error(f"Erro ao inserir dados: {str(err)}", exc_info=True) # Logando erro com traceback + return jsonify({'erro': f'Erro ao inserir dados: {str(err)}'}), 500 + + finally: + cursor.close() diff --git a/app/routes/newzabbix.py b/app/routes/newzabbix.py new file mode 100644 index 0000000..a383f62 --- /dev/null +++ b/app/routes/newzabbix.py @@ -0,0 +1,48 @@ +from pyzabbix import ZabbixAPI + +# Connect to the Zabbix server +zapi = ZabbixAPI("https://mimir.itguys.com.br/zabbix/api_jsonrpc.php") + +# Login to the Zabbix API +zapi.login(token="10925e9e452cade5270f4d930feb3b5e1aa2cc9b366c1c5b4d72996212b12c93") + +# Retrieve a list of host groups (not hosts themselves) +groups = zapi.hostgroup.get(output="extend") + +# Print group information and metrics +for group in groups: + print(f"Group ID: {group['groupid']}, Group Name: {group['name']}") + + # Retrieve hosts in this group + hosts = zapi.host.get(groupids=group['groupid'], output="extend") + + for host in hosts: + print(f" Host Name: {host['name']}") + + # Retrieve items (metrics) for each host + items = zapi.item.get(hostids=host['hostid'], output="extend", + filter={"key_": ["system.uptime", "net.if.in", "net.if.out", "vm.memory.size", "vfs.fs.size"]}) + + # Print metrics for each host + for item in items: + # Check which metric it corresponds to and print it + if item['key_'] == "system.uptime": + print(f" Uptime: {item['lastvalue']} seconds") + elif item['key_'] == "net.if.in": + print(f" Network In: {item['lastvalue']} bytes") + elif item['key_'] == "net.if.out": + print(f" Network Out: {item['lastvalue']} bytes") + elif item['key_'] == "vm.memory.size": + print(f" Memory Usage: {item['lastvalue']} bytes") + elif item['key_'] == "vfs.fs.size": + print(f" Disk Usage: {item['lastvalue']} bytes") + + # Retrieve the network packet loss (example metric) + # This can vary depending on your Zabbix configuration for ping or similar metrics + network_packet_loss = zapi.item.get(hostids=host['hostid'], + filter={"key_": "net.ping.loss"}, output="extend") + for loss in network_packet_loss: + print(f" Packet Loss: {loss['lastvalue']} %") + +# Logout from the Zabbix API +zapi.user.logout() diff --git a/app/routes/servicos.py b/app/routes/servicos.py new file mode 100644 index 0000000..2156e0e --- /dev/null +++ b/app/routes/servicos.py @@ -0,0 +1,55 @@ +from flask import Blueprint, jsonify +from flask_mysqldb import MySQL +from .auth import token_required + +servicos = Blueprint('servicos', __name__) + +mysql = MySQL() # Instância do MySQL será configurada no app principal + +@servicos.route('/servicos', methods=['GET']) +@token_required +def listar_servicos(data): + try: + domain = data.get('domain', '') # Obtém o domínio do usuário do token + if not domain: + return jsonify({"status": "error", "message": "Usuário não autenticado!"}), 401 + + # Conecta ao banco de dados e consulta os serviços + cur = mysql.connection.cursor() + + query = """ + SELECT `servico1`, `servico2`, `servico3`, `servico4`, `servico5`, + `servico6`, `servico9`, `servico12` + FROM `servicos` WHERE `dominio` = %s + """ + cur.execute(query, (domain,)) + results = cur.fetchall() + cur.close() + + + # Verificando se resultados foram retornados + if results: + # Quando a consulta retorna uma tupla com dicionário, acessamos o primeiro item da tupla + row = results[0] # A primeira linha é um dicionário + servicos_prestados = { + "servico1": row.get('servico1'), + "servico2": row.get('servico2'), + "servico3": row.get('servico3'), + "servico4": row.get('servico4'), + "servico5": row.get('servico5'), + "servico6": row.get('servico6'), + "servico9": row.get('servico9'), + "servico12": row.get('servico12'), + } + + return jsonify(servicos_prestados), 200 + else: + return jsonify({"erro": "Nenhum serviço encontrado"}), 404 + except Exception as e: + print(f"Erro interno: {e}") # Print detalhado do erro + return jsonify({"status": "error", "message": "Erro interno"}), 500 + + + + + diff --git a/app/routes/upload_img.py b/app/routes/upload_img.py new file mode 100644 index 0000000..7dadbe6 --- /dev/null +++ b/app/routes/upload_img.py @@ -0,0 +1,88 @@ +from flask_mysqldb import MySQL +from flask import Flask, Blueprint, jsonify, request +from .auth import token_required +import os +import traceback +import MySQLdb + +imagem = Blueprint('imagem', __name__) +mysql = MySQL() + +CAMINHO_PERFIL = "/var/www/Backend/itguys/ambiente_python/repositorio_img/perfil/" +CAMINHO_FUNDOS = "/var/www/Backend/itguys/ambiente_python/repositorio_img/fundos/" + +def salvar_imagem(arquivo, tipo_imagem, nome_usuario): + """Salva a imagem no diretório correspondente e retorna o caminho relativo""" + nome_arquivo = f"{nome_usuario}.jpg" + + if tipo_imagem == "perfil": + caminho_diretorio = CAMINHO_PERFIL + caminho_relativo = f"perfil/{nome_arquivo}" + else: + caminho_diretorio = CAMINHO_FUNDOS + caminho_relativo = f"fundos/{nome_arquivo}" + + caminho_completo = os.path.join(caminho_diretorio, nome_arquivo) + + # Garante que o diretório existe + os.makedirs(caminho_diretorio, exist_ok=True) + + # Salva a imagem + arquivo.save(caminho_completo) + + return caminho_relativo # Retorna o caminho relativo para o banco de dados + +def get_db_connection(): + """Verifica e retorna uma conexão válida com o banco de dados""" + try: + conn = mysql.connection + conn.ping() # Verifica se a conexão está ativa + return conn + except MySQLdb.OperationalError: + return mysql.connection # Tenta criar uma nova conexão + +@imagem.route('/imagem', methods=['POST']) +@token_required +def receber_imagem(data): + try: + nome_usuario = data.get('user', '') # Separa o usuário do dominío + if not nome_usuario: + return jsonify({"status": "error", "message": "Usuário não autenticado!"}), 405 + + nome_usuario = nome_usuario.split('@')[0] + + + imagem_perfil = request.files.get('perfil') + imagem_foto_fundo = request.files.get('foto_fundo') + + # Verifica se as imagens foram enviadas corretamente + if not imagem_perfil or not imagem_foto_fundo: + return jsonify({"status": "error", "message": "Imagens não enviadas corretamente!"}), 400 + + # Salva as imagens e obtém os caminhos relativos + caminho_perfil = salvar_imagem(imagem_perfil, "perfil", nome_usuario) + caminho_foto_fundo = salvar_imagem(imagem_foto_fundo, "fundo", nome_usuario) + + # Conecta-se ao banco e executa a query de atualização + conn = get_db_connection() + cursor = conn.cursor() + + query = """ + UPDATE usuarios + SET img_perfil = %s, img_fundo = %s + WHERE usuario = %s + """ + valores = (caminho_perfil, caminho_foto_fundo, nome_usuario) + + cursor.execute(query, valores) + conn.commit() + cursor.close() + + return jsonify({"status": "success", "message": "Imagens enviadas e salvas com sucesso!"}), 200 + + except MySQLdb.OperationalError as e: + return jsonify({"status": "error", "message": f"Erro de conexão com o banco de dados: {str(e)}"}), 500 + except Exception as e: + traceback.print_exc() + return jsonify({"status": "error", "message": str(e)}), 500 + diff --git a/app/routes/zammad.py b/app/routes/zammad.py index a9ac65a..b1c2478 100644 --- a/app/routes/zammad.py +++ b/app/routes/zammad.py @@ -1,9 +1,12 @@ import requests +from dotenv import load_dotenv -base_url = "http://zammad.itguys.com.br/api/v1" -zammad_token = "kT0IXO8aVhPoTLcMRNL290rqd9jbRhhM0zf8MgBo3n00NLChToSU6rOGnMgWA0M2" +load_dotenv() -def listar_tickets(domain): +base_url = "https://zammad.itguys.com.br/api/v1" +zammad_token = "QiFbQ7txT0BS_3N8GrwOzAS6f7ziVTa1VqcGGpaPFscvdcfnBVjgq699fFj6NpQW" #Token expira em 2065 + +def listar_tickets(domain, limit=500, offset=0): try: headers = { "Authorization": f"Token token={zammad_token}", diff --git a/keyinter.pem b/keyinter.pem new file mode 100644 index 0000000..1de8c45 --- /dev/null +++ b/keyinter.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCXx+9g4l6QwnUE +f2b3mVA73MsQbXnc9m6hIGAS8Innba0mUA+nWij5KALUsJJEtoM7GGUlsijQEgLn ++6V7pCYAy1qgL6q357xDNPw8qbshf9LOmPOJXsc0cqUSI0J4YLTjuJhM5a9zzje5 +RWJwwFl9Ileh3MT1FggLihNmcHzeC+VpWTvFXI/gC6KaDT0Xh1lNCN4jTpNEGCI8 +0kOfT6KUpZFRfYcazTCcPYlfvAY8H6aRXTPlGy/QXUPsiwhrdN0yzIF3PFfSFrP9 +tIH9HlnExMdndvNig9Z3lxIp6di7UXIVMod5sWEgXLZXPqRtqRU6CtZkMXHKDx3O +5OcpTN1bAgMBAAECggEAC9e4SEVxXnclvTuZk6EdPwZ7u6TnGMQLnrvRczjccbe/ +hllB12tz/fjOu7ypNP5On/pHzhioEZAONP6QC2Uj5/T19cCyX9YPfOjx82PE65i3 +IJKTkfjYrzFwyskAgzb8djYtf/Z96ZnCBE0zIJwJf3eCAemhXoQhDZFw8RG+1G5X +YtOoItBE5oIAXuUe3pYTaMY/1XnGe/vynFKeIcU9O2v6E3au8oueevqppmhfHkiM +a6gtNhjU3wpii3ZJk/L4Cpka752CjbXrZCaU1qMXB4hNkSuOi1Hq9clU91Fz4PXw +MHzeAZInlH3J29uxvDlGoMwTvpFIL2iRnrVzr40AfQKBgQC6+q31kAi818ciXxvh +ZxyEJEwQw/q5x/pTZQ2VRJB3kBpt7Lq570IZfDpaOsPg2wB/4SbE8XHpX7FzJAMd +BDCAzkBl8+fREbfL57/KKxV2EoHRfazSx23w8f5N5R+/OcXErgOAGUzcF2T53yXU +TXDpzgjTOEU/4p+h7wqceSenNwKBgQDPzxB0Xk8oYHWejIWVRuLV0US+kTxFiLX4 +rrRppdk52oEzZFKJ0rosf00fHtxIyqW2NdPQlkphmyMjRUw3fPedK/FvNU8PnTo6 +3MJ61QRgGSAi6/YMIs9K/Y83iFRKTBynZi36UCOUZbEncpZXuiOmplJWWE17FmHj +5IFItd5E/QKBgQCVD/oVVcGRg1iO71HTzZcvRZyalRLSfznyuBIvGN0vZGOdlOd8 +CeEhXidK/aRhI1bvm/iDc5UDnzVhfKk6vbdJSKSQYvVBeKWVWmlM7DIM0k5KS622 +0CS2vMWnJe28Tnt7A9toiUL8B26Jwbtv2FkXHBlvAmI6vxnSSDambfQN2wKBgQCm +IYqtDUxJIjxFwV91xJLJjyBfHSrLCA06PyjaIQ11c9rAZB6cMkxGEItuKrS+uMsb +zRKF+fCC8Yx4wQi6f3xROXUti7el6vNHZX9QxYVW8h8/69XrQ9Tmxai+I44HS6vI +pCZzq6eWFmo2+CN7BMNFkkfW4YcntPATSXWV1FdaXQKBgQC3mKzwS/3GZ4NOarCL +ISXGef+QZLPYj4eV08ccmRYXjlBR6rA2BNn9vPayB1E/IqG91Rj2tENLiE/NjVkG +ZuAss8FdQS19oiPRPEA+u11+pNy0RfJ9uxjrP9l//x8lA0cw/Pv6S/m2c+1DSjVd +UD2LwbNvaS6W4Vhy53LNGpbwmQ== +-----END PRIVATE KEY----- diff --git a/privkeyinter.pem b/privkeyinter.pem new file mode 100644 index 0000000..b5043ba --- /dev/null +++ b/privkeyinter.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLXKbJUo6/xfnj +1f6Pt/wKw4Ko4tS0WiK+DSfzXBuEStHtXvcB5PPbnMJ5KNGQiPcFq5rkcwlERg8F +Z/+hjhuyn1as4fMxquKTBH7FpYHMRbuURSXtp9aZGMf6oMc1lzWF3aVQEgGPcAi4 +Pbp9ddFb4vhu/INe+At4WiQvWK0mD+TfX2XFdUcl1cNUQCz0VfeuBGpnjKApIqd3 +2ed2wF7U7bYBic2p9TA4Fw+VYArng12AbV5f9BQWuUUhjRSM7rYFs/R2bOHhB3y0 +5EP72jwqwYnXVZMKGOomq4Vhrdj0VmUjxC2r3iui+tH2HteHCNzNMrcoTOn+ag1/ +lHfTZK41AgMBAAECggEAJ80wtI70suqB09qGeeT5zraAvGK23DyW96j2BH6mwQ/u +wd1YDVYc90LZWiLHz1jLNiAlzugH7IWku3tlEB7S43Ulnu0TLsmiEkGrOS5BNvR/ +989H0tmKWgj8XNx6WM4JMvPUPtVjWkpEXqDwPs1gJjKISpqf8KauAgZsdhrOOrhA +w+2qmOd/5w7oZCNu9sm53XoR6pSifdpRl+AjY+XRK+/hfyD3DqLJoZcW5al2ZHsh +iUWgfDDexFXVEeSc9OSyh5vTVXweXv8WVbpxAcD3l7Bsi7hltPW4bxyUcXjVfNy4 +rjITSASeVOgI4Kwguwl4WuTd4iMHgopPsKxZqP+1QQKBgQDs5ka//ie79V0I+wDY +Y5vLSRRb9rLg0MDQxNUs9Gsg/+cYiaJrBEh1V+RTKWVEfxHS/hcUvMPgmW73EHRb +vVp652bwcGd3RVY0cOoID6267lqoWim8h0hv5yF82tcRVr5TJO/6DUlpXKgDiDyi +Zqe1Sf/j3mCE0opnByQrX+2MdQKBgQDbwiR6MryH1xZR0O+OFKmnpcxoda3xSoZi +JNxlw/d3U69iPKnV0w7YN4a5ytG2+fLvb2X8FUrvpGBn2TCTOCMvCFHWN9FrAUqA +HhTGHq3HGhA1DnGby+sE6Wn1kLfBYTS/PCusnqXgSVb/NpBqV4uSprweLVwfr2mN +bt9zHkViwQKBgQDbHIIDwkduCZtrWv2FJ1xJweYaySrZ1TsB3YxucANGGmrcvzCC +WwvJvOlqIbeQixcpV+pxO8bQThncWlPFJnYxhyYm7VBFeNQq3OUZX6cIZr1jSUGh +Jl9RYS4QFTkmyFxw+pEbbn6f/RtJaRDsBJbJjxAm6t/K+hEZCfniRG+qoQKBgEyb +axfmI+6+vhsbWMcQ0OuOUql/jHl2303LR8F6BQRl+denChVuE9iv0pll6KF+lH9/ +N/AehBbyGGFbRyGrCijVH6IrpydENfJfiiJeg3nKzieQt232MiFuNO/T2Rrihf68 +PQVZ8L01E8y3+rP3fMJMuXtTmK+6+HLDWcXJoaqBAoGAdHcfcm1S1NNpizSlpAvv +WGmCBxSa4qz5/22RnuL0tSnOd59Uiwp0u6SKSSc+fhw7oMpWQYq8QnsAXjsit0P4 +GRmb5Ox/fHR0oF6IclmWmZin6c5ZeIDYDuGBig1/c6doG1j6WkHJO7xVQ04t7CcA +jk4uwg6pRoaTCArAU3+1Pzk= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/python/keyinter.pem b/python/keyinter.pem new file mode 100644 index 0000000..1de8c45 --- /dev/null +++ b/python/keyinter.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCXx+9g4l6QwnUE +f2b3mVA73MsQbXnc9m6hIGAS8Innba0mUA+nWij5KALUsJJEtoM7GGUlsijQEgLn ++6V7pCYAy1qgL6q357xDNPw8qbshf9LOmPOJXsc0cqUSI0J4YLTjuJhM5a9zzje5 +RWJwwFl9Ileh3MT1FggLihNmcHzeC+VpWTvFXI/gC6KaDT0Xh1lNCN4jTpNEGCI8 +0kOfT6KUpZFRfYcazTCcPYlfvAY8H6aRXTPlGy/QXUPsiwhrdN0yzIF3PFfSFrP9 +tIH9HlnExMdndvNig9Z3lxIp6di7UXIVMod5sWEgXLZXPqRtqRU6CtZkMXHKDx3O +5OcpTN1bAgMBAAECggEAC9e4SEVxXnclvTuZk6EdPwZ7u6TnGMQLnrvRczjccbe/ +hllB12tz/fjOu7ypNP5On/pHzhioEZAONP6QC2Uj5/T19cCyX9YPfOjx82PE65i3 +IJKTkfjYrzFwyskAgzb8djYtf/Z96ZnCBE0zIJwJf3eCAemhXoQhDZFw8RG+1G5X +YtOoItBE5oIAXuUe3pYTaMY/1XnGe/vynFKeIcU9O2v6E3au8oueevqppmhfHkiM +a6gtNhjU3wpii3ZJk/L4Cpka752CjbXrZCaU1qMXB4hNkSuOi1Hq9clU91Fz4PXw +MHzeAZInlH3J29uxvDlGoMwTvpFIL2iRnrVzr40AfQKBgQC6+q31kAi818ciXxvh +ZxyEJEwQw/q5x/pTZQ2VRJB3kBpt7Lq570IZfDpaOsPg2wB/4SbE8XHpX7FzJAMd +BDCAzkBl8+fREbfL57/KKxV2EoHRfazSx23w8f5N5R+/OcXErgOAGUzcF2T53yXU +TXDpzgjTOEU/4p+h7wqceSenNwKBgQDPzxB0Xk8oYHWejIWVRuLV0US+kTxFiLX4 +rrRppdk52oEzZFKJ0rosf00fHtxIyqW2NdPQlkphmyMjRUw3fPedK/FvNU8PnTo6 +3MJ61QRgGSAi6/YMIs9K/Y83iFRKTBynZi36UCOUZbEncpZXuiOmplJWWE17FmHj +5IFItd5E/QKBgQCVD/oVVcGRg1iO71HTzZcvRZyalRLSfznyuBIvGN0vZGOdlOd8 +CeEhXidK/aRhI1bvm/iDc5UDnzVhfKk6vbdJSKSQYvVBeKWVWmlM7DIM0k5KS622 +0CS2vMWnJe28Tnt7A9toiUL8B26Jwbtv2FkXHBlvAmI6vxnSSDambfQN2wKBgQCm +IYqtDUxJIjxFwV91xJLJjyBfHSrLCA06PyjaIQ11c9rAZB6cMkxGEItuKrS+uMsb +zRKF+fCC8Yx4wQi6f3xROXUti7el6vNHZX9QxYVW8h8/69XrQ9Tmxai+I44HS6vI +pCZzq6eWFmo2+CN7BMNFkkfW4YcntPATSXWV1FdaXQKBgQC3mKzwS/3GZ4NOarCL +ISXGef+QZLPYj4eV08ccmRYXjlBR6rA2BNn9vPayB1E/IqG91Rj2tENLiE/NjVkG +ZuAss8FdQS19oiPRPEA+u11+pNy0RfJ9uxjrP9l//x8lA0cw/Pv6S/m2c+1DSjVd +UD2LwbNvaS6W4Vhy53LNGpbwmQ== +-----END PRIVATE KEY----- diff --git a/python/privkeyinter.pem b/python/privkeyinter.pem new file mode 100644 index 0000000..b5043ba --- /dev/null +++ b/python/privkeyinter.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLXKbJUo6/xfnj +1f6Pt/wKw4Ko4tS0WiK+DSfzXBuEStHtXvcB5PPbnMJ5KNGQiPcFq5rkcwlERg8F +Z/+hjhuyn1as4fMxquKTBH7FpYHMRbuURSXtp9aZGMf6oMc1lzWF3aVQEgGPcAi4 +Pbp9ddFb4vhu/INe+At4WiQvWK0mD+TfX2XFdUcl1cNUQCz0VfeuBGpnjKApIqd3 +2ed2wF7U7bYBic2p9TA4Fw+VYArng12AbV5f9BQWuUUhjRSM7rYFs/R2bOHhB3y0 +5EP72jwqwYnXVZMKGOomq4Vhrdj0VmUjxC2r3iui+tH2HteHCNzNMrcoTOn+ag1/ +lHfTZK41AgMBAAECggEAJ80wtI70suqB09qGeeT5zraAvGK23DyW96j2BH6mwQ/u +wd1YDVYc90LZWiLHz1jLNiAlzugH7IWku3tlEB7S43Ulnu0TLsmiEkGrOS5BNvR/ +989H0tmKWgj8XNx6WM4JMvPUPtVjWkpEXqDwPs1gJjKISpqf8KauAgZsdhrOOrhA +w+2qmOd/5w7oZCNu9sm53XoR6pSifdpRl+AjY+XRK+/hfyD3DqLJoZcW5al2ZHsh +iUWgfDDexFXVEeSc9OSyh5vTVXweXv8WVbpxAcD3l7Bsi7hltPW4bxyUcXjVfNy4 +rjITSASeVOgI4Kwguwl4WuTd4iMHgopPsKxZqP+1QQKBgQDs5ka//ie79V0I+wDY +Y5vLSRRb9rLg0MDQxNUs9Gsg/+cYiaJrBEh1V+RTKWVEfxHS/hcUvMPgmW73EHRb +vVp652bwcGd3RVY0cOoID6267lqoWim8h0hv5yF82tcRVr5TJO/6DUlpXKgDiDyi +Zqe1Sf/j3mCE0opnByQrX+2MdQKBgQDbwiR6MryH1xZR0O+OFKmnpcxoda3xSoZi +JNxlw/d3U69iPKnV0w7YN4a5ytG2+fLvb2X8FUrvpGBn2TCTOCMvCFHWN9FrAUqA +HhTGHq3HGhA1DnGby+sE6Wn1kLfBYTS/PCusnqXgSVb/NpBqV4uSprweLVwfr2mN +bt9zHkViwQKBgQDbHIIDwkduCZtrWv2FJ1xJweYaySrZ1TsB3YxucANGGmrcvzCC +WwvJvOlqIbeQixcpV+pxO8bQThncWlPFJnYxhyYm7VBFeNQq3OUZX6cIZr1jSUGh +Jl9RYS4QFTkmyFxw+pEbbn6f/RtJaRDsBJbJjxAm6t/K+hEZCfniRG+qoQKBgEyb +axfmI+6+vhsbWMcQ0OuOUql/jHl2303LR8F6BQRl+denChVuE9iv0pll6KF+lH9/ +N/AehBbyGGFbRyGrCijVH6IrpydENfJfiiJeg3nKzieQt232MiFuNO/T2Rrihf68 +PQVZ8L01E8y3+rP3fMJMuXtTmK+6+HLDWcXJoaqBAoGAdHcfcm1S1NNpizSlpAvv +WGmCBxSa4qz5/22RnuL0tSnOd59Uiwp0u6SKSSc+fhw7oMpWQYq8QnsAXjsit0P4 +GRmb5Ox/fHR0oF6IclmWmZin6c5ZeIDYDuGBig1/c6doG1j6WkHJO7xVQ04t7CcA +jk4uwg6pRoaTCArAU3+1Pzk= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/repositorio_img/fundos/daivid.alves.jpg b/repositorio_img/fundos/daivid.alves.jpg index 8f3c45f..b0a177c 100644 Binary files a/repositorio_img/fundos/daivid.alves.jpg and b/repositorio_img/fundos/daivid.alves.jpg differ diff --git a/repositorio_img/fundos/gabriel.benetti.jpg b/repositorio_img/fundos/gabriel.benetti.jpg new file mode 100644 index 0000000..ce69cf8 Binary files /dev/null and b/repositorio_img/fundos/gabriel.benetti.jpg differ diff --git a/repositorio_img/fundos/mario.neto.jpg b/repositorio_img/fundos/mario.neto.jpg index 5214c49..d82224f 100644 Binary files a/repositorio_img/fundos/mario.neto.jpg and b/repositorio_img/fundos/mario.neto.jpg differ diff --git a/repositorio_img/fundos/vitoria.oliveira.jpg b/repositorio_img/fundos/vitoria.oliveira.jpg index 872e1ed..6be1c8c 100644 Binary files a/repositorio_img/fundos/vitoria.oliveira.jpg and b/repositorio_img/fundos/vitoria.oliveira.jpg differ diff --git a/repositorio_img/logos/Ferreira_Real.png b/repositorio_img/logos/Ferreira_Real.png new file mode 100644 index 0000000..240662d Binary files /dev/null and b/repositorio_img/logos/Ferreira_Real.png differ diff --git a/repositorio_img/logos/IBAPRJ.png b/repositorio_img/logos/IBAPRJ.png new file mode 100644 index 0000000..d1156e4 Binary files /dev/null and b/repositorio_img/logos/IBAPRJ.png differ diff --git a/repositorio_img/logos/Integramende.png b/repositorio_img/logos/Integramende.png new file mode 100644 index 0000000..ef59af9 Binary files /dev/null and b/repositorio_img/logos/Integramende.png differ diff --git a/repositorio_img/logos/Oeste_Pan.png b/repositorio_img/logos/Oeste_Pan.png new file mode 100644 index 0000000..bced90c Binary files /dev/null and b/repositorio_img/logos/Oeste_Pan.png differ diff --git a/repositorio_img/logos/Pralog.png b/repositorio_img/logos/Pralog.png new file mode 100644 index 0000000..be39914 Binary files /dev/null and b/repositorio_img/logos/Pralog.png differ diff --git a/repositorio_img/logos/Zstation.png b/repositorio_img/logos/Zstation.png new file mode 100644 index 0000000..d38bbf5 Binary files /dev/null and b/repositorio_img/logos/Zstation.png differ diff --git a/repositorio_img/logos/anatram.png b/repositorio_img/logos/anatram.png index 9d10679..7491d19 100644 Binary files a/repositorio_img/logos/anatram.png and b/repositorio_img/logos/anatram.png differ diff --git a/repositorio_img/logos/enseg.png b/repositorio_img/logos/enseg.png index 9d10679..5ced7e5 100644 Binary files a/repositorio_img/logos/enseg.png and b/repositorio_img/logos/enseg.png differ diff --git a/repositorio_img/perfil/gabriel.benetti.jpg b/repositorio_img/perfil/gabriel.benetti.jpg new file mode 100644 index 0000000..44d0a5c Binary files /dev/null and b/repositorio_img/perfil/gabriel.benetti.jpg differ diff --git a/repositorio_img/perfil/mario.neto.jpg b/repositorio_img/perfil/mario.neto.jpg index 90e3560..1862770 100644 Binary files a/repositorio_img/perfil/mario.neto.jpg and b/repositorio_img/perfil/mario.neto.jpg differ diff --git a/repositorio_img/perfil/vitoria.oliveira.jpg b/repositorio_img/perfil/vitoria.oliveira.jpg index e7a2387..6be1c8c 100644 Binary files a/repositorio_img/perfil/vitoria.oliveira.jpg and b/repositorio_img/perfil/vitoria.oliveira.jpg differ diff --git a/tokeninter.txt b/tokeninter.txt new file mode 100644 index 0000000..e530968 --- /dev/null +++ b/tokeninter.txt @@ -0,0 +1 @@ +49a8c9c3-aac6-44fe-bc8d-f295677b96a6 \ No newline at end of file