Compare commits
No commits in common. "0.1V_AMBK" and "main" have entirely different histories.
12
python/.env
12
python/.env
|
|
@ -1,12 +0,0 @@
|
||||||
JWT_SECRET=4bc7bf3a6b07c87821256d9eb2d607e00692739b0c87e872ae2d8be2678c66bc
|
|
||||||
SESSION_SECRET=d702717e2361ba1a31ce3b98d28ee3e24e2e6a9be8e2afd8e004f842563bacbd
|
|
||||||
REFRESH_TOKEN_SECRET=f6e322f87721cdb8b4464b543ca70ca174ab3cac87f5d34b348d6f1f1ccd4f87
|
|
||||||
MYSQL_HOST=10.10.253.56
|
|
||||||
MYSQL_USER=remote
|
|
||||||
MYSQL_PASSWORD=wNTDu1k79z{(
|
|
||||||
MYSQL_DB=itguys
|
|
||||||
SMTP_USERNAME=contato.site@itguys.com.br
|
|
||||||
SMTP_PASSWORD=j5j@QaSB\Z4<)W]M|hOYbC\605zfGcv:
|
|
||||||
SMTP_HOST=172.16.150.150
|
|
||||||
SMTP_PORT=465
|
|
||||||
SMTP_RECIPIENT=comercial@itguys.com.br
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDojCCAyegAwIBAgISAxzDNNJ+D1PrnQBdJr/XblhmMAoGCCqGSM49BAMDMDIx
|
|
||||||
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
|
|
||||||
NTAeFw0yNDA3MTgxOTE1MzlaFw0yNDEwMTYxOTE1MzhaMBwxGjAYBgNVBAMTEWRl
|
|
||||||
di5pdGd1eXMuY29tLmJyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE+OCuDmslFa26
|
|
||||||
pscnWiCESN+KsGgeEZSxAzDFMmJ0ck6wAZS2xdcFz7JJD3vHXnLSSbcJs65RotpW
|
|
||||||
Nu5MfiHyrkQe5cWYn0viyMZnnVl+ojKcDkDN24/hcsQcevr7Qm11o4ICFDCCAhAw
|
|
||||||
DgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAM
|
|
||||||
BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSCqHCjFtevuQn0TV9XYV+xrAlogjAfBgNV
|
|
||||||
HSMEGDAWgBSfK1/PPCFPnQS37SssxMZwi9LXDTBVBggrBgEFBQcBAQRJMEcwIQYI
|
|
||||||
KwYBBQUHMAGGFWh0dHA6Ly9lNS5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0
|
|
||||||
cDovL2U1LmkubGVuY3Iub3JnLzAcBgNVHREEFTATghFkZXYuaXRndXlzLmNvbS5i
|
|
||||||
cjATBgNVHSAEDDAKMAgGBmeBDAECATCCAQUGCisGAQQB1nkCBAIEgfYEgfMA8QB2
|
|
||||||
AN/hVuuqBa+1nA+GcY2owDJOrlbZbqf1pWoB0cE7vlJcAAABkMd8ctUAAAQDAEcw
|
|
||||||
RQIhAJaDpgmOCf/Z4lLL3gZfo1SMIEoSD6JjVBogpQexgEH5AiB8SHzgLDF9z4rk
|
|
||||||
DcUZVpukXMF+OtcuValcNEpfkZffpQB3AEiw42vapkc0D+VqAvqdMOscUgHLVt0s
|
|
||||||
gdm7v6s52IRzAAABkMd8cg0AAAQDAEgwRgIhAIvVuiNpWs0HSrUj1RHt/76L00kB
|
|
||||||
+E+MbdQF/5uMaOlEAiEApu3u5t3vrZRdt2UpTiu7Uzzl1mDWd4fC7Pmbf1HPIqgw
|
|
||||||
CgYIKoZIzj0EAwMDaQAwZgIxAMom8JO8+pOT2PpHj+cUNC3UnrbYMfrKq40gjdxH
|
|
||||||
qLA28Fo2sBBo6WSPAXSHJ23oZwIxAK60hbs1MVqUSXR8vxLEni48kc6gJ4Al4s8l
|
|
||||||
Ncumyp1du4+bi8j5oNZ7btZg8cDuig==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw
|
|
||||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
|
||||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
|
||||||
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
|
||||||
RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK
|
|
||||||
a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO
|
|
||||||
VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw
|
|
||||||
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
|
|
||||||
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw
|
|
||||||
i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
|
|
||||||
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
|
|
||||||
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
|
|
||||||
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C
|
|
||||||
2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+
|
|
||||||
bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG
|
|
||||||
6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV
|
|
||||||
XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO
|
|
||||||
koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq
|
|
||||||
cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI
|
|
||||||
E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e
|
|
||||||
K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX
|
|
||||||
GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL
|
|
||||||
sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd
|
|
||||||
VQD9F6Na/+zmXCc=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"imagem_Cab": "",
|
|
||||||
"A_cab": "./Tela_Monitoramento/Monitoramento copy.html",
|
|
||||||
"button_Cab": "Logout",
|
|
||||||
"imagem_segumento_1": "../Acessts/Imagens/Iconis/seta-direita.png",
|
|
||||||
"imagem_User_1_segumento_2": "../Acessts/Imagens/Iconis/profile-user.png",
|
|
||||||
"imagem_User_2_segumento_2": "../Acessts/Imagens/Iconis/profile-user.png",
|
|
||||||
"texto_User_segumento_2": "Usuario",
|
|
||||||
"texto_Empresa_segumento_2": "Anatram",
|
|
||||||
"Menu_home_a": "http://grafana.itguys.com.br:3000/dashboard/snapshot/6sVz7BNJVCY4sZD0m9P40k7nFEc5MqLI?kiosk",
|
|
||||||
"Menu_home_img": "../Acessts/Imagens/Iconis/home.png",
|
|
||||||
"Menu_home_text": "Home",
|
|
||||||
"Menu_Monitor_a": "./Tela_Monitoramento/Monitoramento copy.html",
|
|
||||||
"Menu_Monitor_img": "../Acessts/Imagens/Iconis/monitor.png",
|
|
||||||
"Menu_Monitor_text": "Monitoramento",
|
|
||||||
"Menu_Servicedesk_a": "https://servicedesk.itguys.com.br/HomePage.do",
|
|
||||||
"Menu_Servicedesk_img": "../Acessts/Imagens/Iconis/technical-support.png",
|
|
||||||
"Menu_Servicedesk_text": "Servicedesk",
|
|
||||||
"Menu_Suporte_a": "https://api.whatsapp.com/send?phone=5521966344698",
|
|
||||||
"Menu_Suporte_img": "../Acessts/Imagens/Iconis/central-de-atendimento.png",
|
|
||||||
"Menu_Suporte_text": "Suporte",
|
|
||||||
"Menu_Config_a": "./Tela_config/Config_Ambiente_usuario.html",
|
|
||||||
"Menu_Config_img": "../Acessts/Imagens/Iconis/engrenagem - Copia.png",
|
|
||||||
"Menu_Config_text": "Configuracões",
|
|
||||||
"Tela": "http://grafana.itguys.com.br:3000/dashboard/snapshot/6sVz7BNJVCY4sZD0m9P40k7nFEc5MqLI?kiosk"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
{
|
|
||||||
"info_html": [
|
|
||||||
{
|
|
||||||
"imagem_Cab": "",
|
|
||||||
"A_cab": "..",
|
|
||||||
"button_Cab": "Logout",
|
|
||||||
"imagem_segumento_1": "../Acessts/Imagens/Iconis/seta-direita.png",
|
|
||||||
"imagem_User_1_segumento_2": "../Acessts/Imagens/Iconis/profile-user.png",
|
|
||||||
"imagem_User_2_segumento_2": "../Acessts/Imagens/Iconis/profile-user.png",
|
|
||||||
"texto_User_segumento_2": "Usuario",
|
|
||||||
"texto_Empresa_segumento_2": "itguys",
|
|
||||||
"Menu_home_a": "../Ambiente do usuario/Tela_home/Home_page.html",
|
|
||||||
"Menu_home_img": "../Acessts/Imagens/Iconis/home.png",
|
|
||||||
"Menu_home_text": "Home",
|
|
||||||
"Menu_Monitor_a": "./Tela_Monitoramento/Monitoramento copy.html",
|
|
||||||
"Menu_Monitor_img": "../Acessts/Imagens/Iconis/monitor.png",
|
|
||||||
"Menu_Monitor_text": "Monitoramento",
|
|
||||||
"Menu_Servicedesk_a": "https://servicedesk.itguys.com.br/HomePage.do",
|
|
||||||
"Menu_Servicedesk_img": "../Acessts/Imagens/Iconis/technical-support.png",
|
|
||||||
"Menu_Servicedesk_text": "Servicedesk",
|
|
||||||
"Menu_Suporte_a": "https://api.whatsapp.com/send?phone=5521966344698",
|
|
||||||
"Menu_Suporte_img": "../Acessts/Imagens/Iconis/central-de-atendimento.png",
|
|
||||||
"Menu_Suporte_text": "Suporte",
|
|
||||||
"Menu_Config_a": "./Tela_config/Config_Ambiente_usuario.html",
|
|
||||||
"Menu_Config_img": "../Acessts/Imagens/Iconis/engrenagem - Copia.png",
|
|
||||||
"Menu_Config_text": "Configuracões",
|
|
||||||
"Tela": "./Tela_home/Home_page.html"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"config_influxdb": [
|
|
||||||
{
|
|
||||||
"Token": "lLgq7Y2eXZ5Hxc68dkyFULevz5pO1QPjQsk23M0ETe0hWDK8n0Fa2hIfUQxOek8n0IpRcy46U3ioU3C9htr3YA==",
|
|
||||||
"org": "iTGuys",
|
|
||||||
"url": "http://influxdb.itguys.com.br"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"queries": [
|
|
||||||
{
|
|
||||||
"uid": "b6f3a8d4-01a4-4c53-a2a8-123456789abc",
|
|
||||||
"query_name": "Server CPU",
|
|
||||||
"query": "from(bucket: \"${Bucket}\")\n |> range(start: v.timeRangeStart, stop:v.timeRangeStop)\n |> filter(fn: (r) =>\n r._measurement == \"cpustat\" and\n r._field == \"cpu\"\n )\n |> filter(fn: (r) => r[\"host\"] == \"${server}\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean)",
|
|
||||||
"description": "Consulta para obter o uso médio de CPU no último 1 hora."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"uid": "a2b9d8e5-77b4-4f9d-a2b8-abcdef123456",
|
|
||||||
"query_name": "Logical Cores",
|
|
||||||
"query": "from(bucket: \"${Bucket}\")\n |> range(start: v.timeRangeStart, stop:v.timeRangeStop)\n |> filter(fn: (r) =>\n r._measurement == \"cpustat\" and\n r._field == \"cpus\"\n )\n |> filter(fn: (r) => r[\"host\"] == \"${server}\")\n |> limit(n:1)",
|
|
||||||
"description": "Consulta para obter o uso médio de memória no último 1 hora."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"uid": "8e214351-69ca-4160-a72f-17d46e2231ea",
|
|
||||||
"query_name": "Total Memory",
|
|
||||||
"query": "from(bucket: \"${Bucket}\")\n |> range(start: v.timeRangeStart, stop:v.timeRangeStop)\n |> filter(fn: (r) =>\n r._measurement == \"memory\" and\n r._field == \"memtotal\"\n )\n |> filter(fn: (r) => r[\"host\"] == \"${server}\")\n |> limit(n:1)",
|
|
||||||
"description": "Consulta para obter a média de I/O de disco nos últimos 30 minutos."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCLn1GV8AI0K5D46tNo
|
|
||||||
AlfOmKAIUjcEN4lSQ8/zb7fr2xJlb1kEV4CqgqS/pEqClXShZANiAAT44K4OayUV
|
|
||||||
rbqmxydaIIRI34qwaB4RlLEDMMUyYnRyTrABlLbF1wXPskkPe8dectJJtwmzrlGi
|
|
||||||
2lY27kx+IfKuRB7lxZifS+LIxmedWX6iMpwOQM3bj+FyxBx6+vtCbXU=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
Flask==2.3.2 # Framework para criar APIs
|
|
||||||
Flask-MySQLdb==0.2.0 # Integração com MySQL
|
|
||||||
ldap3==2.9 # Biblioteca para autenticação com servidores LDAP
|
|
||||||
python-dotenv==1.0.0 # Carregar variáveis de ambiente de arquivos .env
|
|
||||||
PyJWT==2.6.0 # Para gerar e decodificar tokens JWT
|
|
||||||
Flask-Cors==3.0.10 # Suporte a CORS (Cross-Origin Resource Sharing)
|
|
||||||
Flask-WTF==1.1.1 # Proteção contra CSRF (Cross-Site Request Forgery)
|
|
||||||
Flask-Talisman==0.8.1 # Para melhorar a segurança da aplicação
|
|
||||||
influxdb-client==1.35.0 # Cliente para InfluxDB
|
|
||||||
gunicorn==20.1.0 # Servidor WSGI (opcional, caso deseje usar em produção)
|
|
||||||
487
python/server.py
487
python/server.py
|
|
@ -1,487 +0,0 @@
|
||||||
from flask import Flask, request, jsonify, send_from_directory
|
|
||||||
from flask_mysqldb import MySQL
|
|
||||||
import ldap3
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
from functools import wraps
|
|
||||||
from collections import OrderedDict
|
|
||||||
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_wtf.csrf import CSRFProtect # Importa CSRFProtect para proteção CSRF
|
|
||||||
from flask_talisman import Talisman
|
|
||||||
import influxdb_client, time
|
|
||||||
from influxdb_client import InfluxDBClient, Point, WritePrecision
|
|
||||||
from influxdb_client.client.write_api import SYNCHRONOUS
|
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
||||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
||||||
from cryptography.hazmat.primitives import hashes
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
|
||||||
import ldap3
|
|
||||||
|
|
||||||
# Carregar variáveis de ambiente do arquivo .env
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
# Configuração de cookies seguros
|
|
||||||
app.config['SESSION_COOKIE_SECURE'] = True # Cookies serão enviados apenas em conexões HTTPS
|
|
||||||
app.config['SESSION_COOKIE_HTTPONLY'] = True # Cookies não estarão acessíveis via JavaScript
|
|
||||||
|
|
||||||
Talisman(app)
|
|
||||||
# Configuração da chave secreta necessária para CSRF e JWT
|
|
||||||
app.config['SECRET_KEY'] = os.getenv('JWT_SECRET') or 'sua_chave_secreta' # Defina uma chave secreta segura
|
|
||||||
# Inicializa a proteção CSRF
|
|
||||||
csrf = CSRFProtect(app)
|
|
||||||
|
|
||||||
# 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 do SMTP usando variáveis de ambiente
|
|
||||||
app.config['SMTP_USERNAME'] = os.getenv('SMTP_USERNAME')
|
|
||||||
app.config['SMTP_HOST'] = os.getenv('SMTP_HOST')
|
|
||||||
app.config['SMTP_PASSWORD'] = os.getenv('SMTP_PASSWORD')
|
|
||||||
app.config['SMTP_PORT'] = os.getenv('SMTP_PORT')
|
|
||||||
app.config['SMTP_RECIPIENT'] = os.getenv('SMTP_RECIPIENT')
|
|
||||||
|
|
||||||
mysql = MySQL(app)
|
|
||||||
|
|
||||||
# Função para derivar a chave usando PBKDF2
|
|
||||||
def derive_key(password: bytes, salt: bytes):
|
|
||||||
kdf = PBKDF2HMAC(
|
|
||||||
algorithm=hashes.SHA512(),
|
|
||||||
length=32, # O tamanho da chave de AES-256 é 32 bytes
|
|
||||||
salt=salt,
|
|
||||||
iterations=500000,
|
|
||||||
backend=default_backend()
|
|
||||||
)
|
|
||||||
key = kdf.derive(password)
|
|
||||||
return key
|
|
||||||
|
|
||||||
# Função para descriptografar dados
|
|
||||||
def decrypt_aes_cbc(ciphertext, key, iv):
|
|
||||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
|
|
||||||
decryptor = cipher.decryptor()
|
|
||||||
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
|
|
||||||
return plaintext
|
|
||||||
|
|
||||||
def recebe_smtp_variaveis_env():
|
|
||||||
return {
|
|
||||||
'SMTP_USERNAME': app.config['SMTP_USERNAME'],
|
|
||||||
'SMTP_HOST': app.config['SMTP_HOST'],
|
|
||||||
'SMTP_PASSWORD': app.config['SMTP_PASSWORD'],
|
|
||||||
'SMTP_PORT': app.config['SMTP_PORT'],
|
|
||||||
'SMTP_RECIPIENT': app.config['SMTP_RECIPIENT']
|
|
||||||
}
|
|
||||||
|
|
||||||
def token_required(f):
|
|
||||||
@wraps(f) # Adiciona wraps aqui para manter o nome da função original
|
|
||||||
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
|
|
||||||
|
|
||||||
def get_influxdb_config(domain, mysql):
|
|
||||||
# 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()
|
|
||||||
|
|
||||||
# Verifica se a empresa foi encontrada
|
|
||||||
if empresa_result is None:
|
|
||||||
raise ValueError('Empresa não encontrada no banco de dados')
|
|
||||||
|
|
||||||
# Obtém o nome da empresa (empresa_result é uma tupla)
|
|
||||||
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):
|
|
||||||
raise FileNotFoundError('Arquivo JSON não encontrado para a empresa fornecida')
|
|
||||||
|
|
||||||
# Carregar o conteúdo do arquivo JSON mantendo a ordem
|
|
||||||
with open(json_filepath, 'r') as json_file:
|
|
||||||
json_data = json.load(json_file, object_pairs_hook=OrderedDict)
|
|
||||||
|
|
||||||
return json_data # Retorna todo o JSON carregado
|
|
||||||
|
|
||||||
@app.route('/login', methods=['POST'])
|
|
||||||
@csrf.exempt # Endpoints de autenticação como este podem ser excluídos da proteção CSRF, pois o token CSRF não está disponível antes do login; remova este decorador se quiser aplicar proteção CSRF.
|
|
||||||
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
|
|
||||||
|
|
||||||
@app.route('/mounting', methods=['GET'])
|
|
||||||
@token_required
|
|
||||||
def mounting():
|
|
||||||
# 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]
|
|
||||||
|
|
||||||
# Verifica se o usuário está autenticado
|
|
||||||
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()
|
|
||||||
|
|
||||||
# Verifica se a empresa foi encontrada
|
|
||||||
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
|
|
||||||
|
|
||||||
# Carregar o conteúdo do arquivo JSON mantendo a ordem
|
|
||||||
with open(json_filepath, 'r') as json_file:
|
|
||||||
json_data = json.load(json_file, object_pairs_hook=OrderedDict)
|
|
||||||
|
|
||||||
# Extrair apenas o conteúdo de 'info_html'
|
|
||||||
info_html_content = json_data.get('info_html', {})
|
|
||||||
|
|
||||||
# Retornar a resposta JSON com apenas o conteúdo de 'info_html'
|
|
||||||
return jsonify(info_html_content)
|
|
||||||
|
|
||||||
@app.route('/api/options', methods=['GET'])
|
|
||||||
@token_required
|
|
||||||
@csrf.exempt
|
|
||||||
def get_options():
|
|
||||||
client = None
|
|
||||||
try:
|
|
||||||
# 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]
|
|
||||||
|
|
||||||
# Carregar as configurações do InfluxDB a partir do JSON
|
|
||||||
json_data = get_influxdb_config(domain, mysql)
|
|
||||||
|
|
||||||
# Extrair o token de 'config_influxdb'
|
|
||||||
config_influxdb = json_data.get('config_influxdb', [])
|
|
||||||
|
|
||||||
if not config_influxdb or not isinstance(config_influxdb, list):
|
|
||||||
return jsonify({'msg': 'config_influxdb não encontrado ou inválido'}), 404
|
|
||||||
|
|
||||||
# Acessa o primeiro objeto da lista e obtém os detalhes necessários
|
|
||||||
influxdb_token = config_influxdb[0].get('Token', '')
|
|
||||||
influxdb_org = config_influxdb[0].get('org', '')
|
|
||||||
influxdb_url = config_influxdb[0].get('url', '')
|
|
||||||
|
|
||||||
# Verifica se todos os dados necessários foram encontrados
|
|
||||||
if not influxdb_token:
|
|
||||||
return jsonify({'msg': 'Token não encontrado em config_influxdb'}), 404
|
|
||||||
if not influxdb_org:
|
|
||||||
return jsonify({'msg': 'Org não encontrado em config_influxdb'}), 404
|
|
||||||
if not influxdb_url:
|
|
||||||
return jsonify({'msg': 'URL não encontrado em config_influxdb'}), 404
|
|
||||||
|
|
||||||
# Inicializa o cliente InfluxDB
|
|
||||||
client = influxdb_client.InfluxDBClient(url=influxdb_url, token=influxdb_token, org=influxdb_org)
|
|
||||||
query_api = client.query_api()
|
|
||||||
|
|
||||||
# Consulta para listar os buckets disponíveis
|
|
||||||
buckets_query = '''
|
|
||||||
buckets()
|
|
||||||
'''
|
|
||||||
buckets_result = query_api.query(org=influxdb_org, query=buckets_query)
|
|
||||||
|
|
||||||
# Processa a lista de buckets
|
|
||||||
buckets = []
|
|
||||||
for table in buckets_result:
|
|
||||||
for record in table.records:
|
|
||||||
bucket_name = record.values.get('name') # Acessa diretamente o nome do bucket
|
|
||||||
if bucket_name:
|
|
||||||
buckets.append(bucket_name)
|
|
||||||
|
|
||||||
if len(buckets) == 0:
|
|
||||||
return jsonify({'msg': 'Nenhum bucket encontrado'}), 404
|
|
||||||
|
|
||||||
# Para cada bucket, listar os nodenames diretamente
|
|
||||||
nodenames = {}
|
|
||||||
for bucket in buckets:
|
|
||||||
nodenames_query = f"""
|
|
||||||
from(bucket: \"{bucket}\")
|
|
||||||
|> range(start: -1d)
|
|
||||||
|> keep(columns: [\"nodename\"])
|
|
||||||
|> distinct(column: \"nodename\")
|
|
||||||
"""
|
|
||||||
nodenames_result = query_api.query(org=influxdb_org, query=nodenames_query)
|
|
||||||
|
|
||||||
bucket_nodenames = []
|
|
||||||
for table in nodenames_result:
|
|
||||||
for record in table.records:
|
|
||||||
if record.get_value() is not None: # Ignorar valores nulos
|
|
||||||
bucket_nodenames.append(record.get_value())
|
|
||||||
|
|
||||||
nodenames[bucket] = bucket_nodenames
|
|
||||||
|
|
||||||
# Retorna a lista de buckets e nodenames como resposta JSON
|
|
||||||
return jsonify({
|
|
||||||
"buckets": buckets,
|
|
||||||
"nodenames": nodenames
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({'msg': 'Erro ao recuperar opções', 'error': str(e)}), 500
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if client is not None:
|
|
||||||
client.close()
|
|
||||||
|
|
||||||
@app.route('/api/execute_all_queries', methods=['POST'])
|
|
||||||
@token_required
|
|
||||||
@csrf.exempt
|
|
||||||
def execute_all_queries():
|
|
||||||
client = None
|
|
||||||
try:
|
|
||||||
# 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']
|
|
||||||
domain = username_full.split('@')[1]
|
|
||||||
|
|
||||||
# Carregar as configurações do InfluxDB e queries a partir do JSON
|
|
||||||
json_data = get_influxdb_config(domain, mysql)
|
|
||||||
|
|
||||||
# Extrair as informações da requisição
|
|
||||||
request_data = request.get_json()
|
|
||||||
bucket = request_data.get('bucket')
|
|
||||||
host = request_data.get('host')
|
|
||||||
start_time = request_data.get('startTime')
|
|
||||||
end_time = request_data.get('endTime')
|
|
||||||
window_period = request_data.get('windowPeriod')
|
|
||||||
|
|
||||||
# Inicializa o cliente InfluxDB
|
|
||||||
influxdb_token = json_data['config_influxdb'][0]['Token']
|
|
||||||
influxdb_org = json_data['config_influxdb'][0]['org']
|
|
||||||
influxdb_url = json_data['config_influxdb'][0]['url']
|
|
||||||
client = influxdb_client.InfluxDBClient(url=influxdb_url, token=influxdb_token, org=influxdb_org)
|
|
||||||
query_api = client.query_api()
|
|
||||||
|
|
||||||
# Lista para armazenar os resultados de cada query
|
|
||||||
all_results = []
|
|
||||||
|
|
||||||
# Itera sobre todas as queries no JSON
|
|
||||||
for query_data in json_data['queries']:
|
|
||||||
# Substitui as variáveis na query
|
|
||||||
query_template = query_data['query']
|
|
||||||
query = query_template.replace("${Bucket}", bucket).replace("${server}", host)
|
|
||||||
query = query.replace("v.timeRangeStart", start_time).replace("v.timeRangeStop", end_time)
|
|
||||||
query = query.replace("v.windowPeriod", window_period)
|
|
||||||
|
|
||||||
# Executa a query
|
|
||||||
result = query_api.query(org=influxdb_org, query=query)
|
|
||||||
|
|
||||||
# Processa os resultados da query
|
|
||||||
output = []
|
|
||||||
for table in result:
|
|
||||||
for record in table.records:
|
|
||||||
output.append({
|
|
||||||
"time": record.get_time(),
|
|
||||||
"value": record.get_value(),
|
|
||||||
"measurement": record.get_measurement(),
|
|
||||||
"tags": record.values # Inclui as tags relacionadas ao registro
|
|
||||||
})
|
|
||||||
|
|
||||||
# Adiciona os resultados processados à lista de todas as queries
|
|
||||||
all_results.append({
|
|
||||||
"uid": query_data['uid'],
|
|
||||||
"name": query_data['query_name'],
|
|
||||||
"result": output
|
|
||||||
})
|
|
||||||
|
|
||||||
# Retorna o resultado de todas as queries
|
|
||||||
return jsonify(all_results)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({'msg': 'Erro ao executar as queries', 'error': str(e)}), 500
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if client:
|
|
||||||
client.close()
|
|
||||||
|
|
||||||
@app.route('/api/execute_query/<uid>', methods=['POST'])
|
|
||||||
@token_required
|
|
||||||
@csrf.exempt
|
|
||||||
def execute_query(uid):
|
|
||||||
client = None
|
|
||||||
try:
|
|
||||||
# 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']
|
|
||||||
domain = username_full.split('@')[1]
|
|
||||||
|
|
||||||
# Carregar as configurações de InfluxDB e queries a partir do JSON
|
|
||||||
json_data = get_influxdb_config(domain, mysql)
|
|
||||||
|
|
||||||
# Extrair as informações da requisição
|
|
||||||
request_data = request.get_json()
|
|
||||||
bucket = request_data.get('bucket')
|
|
||||||
host = request_data.get('host')
|
|
||||||
start_time = request_data.get('startTime')
|
|
||||||
end_time = request_data.get('endTime')
|
|
||||||
window_period = request_data.get('windowPeriod')
|
|
||||||
|
|
||||||
# Encontra a query específica com o UID fornecido
|
|
||||||
query_data = next((q for q in json_data['queries'] if q['uid'] == uid), None)
|
|
||||||
|
|
||||||
if not query_data:
|
|
||||||
return jsonify({'msg': 'Consulta não encontrada'}), 404
|
|
||||||
|
|
||||||
# Substitui as variáveis na query
|
|
||||||
query_template = query_data['query']
|
|
||||||
query = query_template.replace("${Bucket}", bucket).replace("${server}", host)
|
|
||||||
query = query.replace("v.timeRangeStart", start_time).replace("v.timeRangeStop", end_time)
|
|
||||||
query = query.replace("v.windowPeriod", window_period)
|
|
||||||
|
|
||||||
# Inicializa o cliente InfluxDB
|
|
||||||
influxdb_token = json_data['config_influxdb'][0]['Token']
|
|
||||||
influxdb_org = json_data['config_influxdb'][0]['org']
|
|
||||||
influxdb_url = json_data['config_influxdb'][0]['url']
|
|
||||||
client = influxdb_client.InfluxDBClient(url=influxdb_url, token=influxdb_token, org=influxdb_org)
|
|
||||||
query_api = client.query_api()
|
|
||||||
|
|
||||||
# Executa a query
|
|
||||||
result = query_api.query(org=influxdb_org, query=query)
|
|
||||||
|
|
||||||
# Processa os resultados da query
|
|
||||||
output = []
|
|
||||||
for table in result:
|
|
||||||
for record in table.records:
|
|
||||||
output.append({
|
|
||||||
"time": record.get_time(),
|
|
||||||
"value": record.get_value(),
|
|
||||||
"measurement": record.get_measurement(),
|
|
||||||
"tags": record.values # Inclui as tags relacionadas ao registro
|
|
||||||
})
|
|
||||||
|
|
||||||
# Retorna o resultado da consulta específica
|
|
||||||
return jsonify({
|
|
||||||
"uid": query_data['uid'],
|
|
||||||
"name": query_data['query_name'],
|
|
||||||
"result": output
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({'msg': 'Erro ao executar a query', 'error': str(e)}), 500
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if client:
|
|
||||||
client.close()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app.run(host="0.0.0.0", port=5000, ssl_context=('./fullchain1.pem', './privkey1.pem'))
|
|
||||||
|
|
@ -0,0 +1,357 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Contatos / iTGuys</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./Css/page/Contatos/contatos.css">
|
||||||
|
<link rel="icon" type="image/x-icon" href="./Acessts/Imagens/iT_Guys/logo1.png">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Bloco focado para os iconis das redes sociais, tendo links para sites externos -->
|
||||||
|
|
||||||
|
<!--Fechamento para os iconis da redes socias -->
|
||||||
|
|
||||||
|
<!--Nav focado na barra de menu do usuario que possui links para cada uma das áreas internas do site-->
|
||||||
|
<header class="Bloco_1">
|
||||||
|
<div class="icon1">
|
||||||
|
<a href="https://www.facebook.com/itguysconsultoria/about">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/facebook.png" alt="" class="icon2">
|
||||||
|
</a>
|
||||||
|
<a href="https://www.instagram.com/itguys.ti/">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/instagram.png" alt="" class="icon2">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://br.linkedin.com/company/itguysconsultoria">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/linkedin.png" alt="" class="icon2">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/o-email.png" alt="" class="icon2">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://api.whatsapp.com/send?phone=5521966344698">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/whatsapp (1).png" alt="" class="icon2">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Menu principal-->
|
||||||
|
|
||||||
|
<nav class="Bloco_nav_1" id="bloco" >
|
||||||
|
|
||||||
|
<a href="./index.html"><img class="Logo" src="./Acessts/Imagens/iT_Guys/logo_340x100.png" alt=""></a>
|
||||||
|
|
||||||
|
<div class="Bloco_nav_2">
|
||||||
|
|
||||||
|
<a href="./Sobre.html">
|
||||||
|
<p class="nav_bloco_iten">Sobre</p>
|
||||||
|
</a>
|
||||||
|
<a href="./Serviços.html">
|
||||||
|
<p class="nav_bloco_iten">Serviços</p>
|
||||||
|
</a>
|
||||||
|
<a href="./Contatos.html">
|
||||||
|
<p class="Contato nav_bloco_iten ">Agende uma consultoria</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="Botao1">
|
||||||
|
<a href="./login.html">
|
||||||
|
<button>Login</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var menu = window.document.getElementById('bloco');
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function() {
|
||||||
|
// Verifica se o scroll vertical é maior que zero
|
||||||
|
if (window.pageYOffset > 0) {
|
||||||
|
|
||||||
|
menu.style.position ='sticky'
|
||||||
|
menu.style.top ='0'
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
menu.style.position ='absolute'
|
||||||
|
menu.style.top ='8vh'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Fechamento do Segundo Header-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--Abertura do Main com todas as principas caracteristicas unicas do pagina home, trazendo um agrupamento em sections as proprias funcionalidades da pagina.-->
|
||||||
|
|
||||||
|
<main>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<article class="capitulo_1">
|
||||||
|
|
||||||
|
<section class="coluna_2">
|
||||||
|
|
||||||
|
<iframe
|
||||||
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3675.326037750306!2d-43.568575725438855!3d-22.9013421792589!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x9be3fb83713bb3%3A0x377c13ebbf176ebc!2sRua%20Tenente%20Ronald%20Santoro%2C%20183%20-%20Campo%20Grande%2C%20Rio%20de%20Janeiro%20-%20RJ%2C%2023080-270!5e0!3m2!1spt-BR!2sbr!4v1718901373199!5m2!1spt-BR!2sbr"
|
||||||
|
width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy"
|
||||||
|
referrerpolicy="no-referrer-when-downgrade">
|
||||||
|
</iframe>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="coluna_1">
|
||||||
|
|
||||||
|
<img src="./Acessts/Imagens/Iconis/pin-de-localizacao.png" alt="">
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="capitulo_2">
|
||||||
|
|
||||||
|
<section class="coluna_1">
|
||||||
|
|
||||||
|
<div class="painel_1">
|
||||||
|
<h2 class="titulo">Funcionamento</h2>
|
||||||
|
<p class="texto_complementar">Segunda á Sexta 09h ás 18h</p>
|
||||||
|
</div>
|
||||||
|
<div class="painel_2">
|
||||||
|
<h2 class="titulo">Endereço</h2>
|
||||||
|
<p class="texto_complementar">Rua Tenente Ronald Santoro, 183 - Campo Grande</p>
|
||||||
|
</div>
|
||||||
|
<div class="painel_3">
|
||||||
|
<h2 class="titulo">Contato</h2>
|
||||||
|
<p class="texto_complementar">Telefone (21) 96634-4698 <br>
|
||||||
|
E-mail:comercial@itguys.com.br</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="coluna_2_email">
|
||||||
|
|
||||||
|
<div class="sub_coluna_1">
|
||||||
|
<h2>Fale com nossa consultoria de Ti e transforme seu negocio</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="sub_coluna_2">
|
||||||
|
|
||||||
|
<div class="particao_1">
|
||||||
|
<img src="./Acessts/Imagens/pexels-karolina-grabowska-5239946.jpg" alt="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="particao_2">
|
||||||
|
<form id="contactForm" action="enviar.php" method="post">
|
||||||
|
|
||||||
|
<div class="formulario_1">
|
||||||
|
<div class="label_1">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
</div>
|
||||||
|
<div class="input_1">
|
||||||
|
<input type="text" name="nome" id="name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="formulario_2">
|
||||||
|
<div class="label_2">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
</div>
|
||||||
|
<div class="input_2">
|
||||||
|
<input type="email" name="email" id="email" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="formulario_3">
|
||||||
|
<div class="label_3">
|
||||||
|
<label for="mensagem">Envie sua mensagem</label>
|
||||||
|
</div>
|
||||||
|
<div class="input_3">
|
||||||
|
<textarea name="mensagem" id="mensagem" required></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit">Enviar</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="responsePopup" class="popup">
|
||||||
|
<div class="popup-content">
|
||||||
|
<span class="closeBtn">×</span>
|
||||||
|
<div id="responseContainer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./js/page/Contatos/pop_up_enviar.js"></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!--Fechamento do main-->
|
||||||
|
|
||||||
|
<!--Rodapé focado na finalização da página tendo caminhos que ainda precisam ser decididos, além da logo da empresa e caminhos para todas as redes socias da propria empresa-->
|
||||||
|
|
||||||
|
<footer class="Bloco_Rodape1">
|
||||||
|
|
||||||
|
<div class="Coluna_Rod_1">
|
||||||
|
<div class="sub_coluna_Rod_1_1">
|
||||||
|
|
||||||
|
<img src="./Acessts/Imagens/iT_Guys/Logo_itGuys - Copia.png" alt="">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sub_coluna_Rod_1_2">
|
||||||
|
<div class="icon1_rod">
|
||||||
|
<a href="https://www.facebook.com/itguysconsultoria/about">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/facebook.png" alt="" class="icon2_rod">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://www.instagram.com/itguys.ti/">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/instagram.png" alt="" class="icon2_rod">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://br.linkedin.com/company/itguysconsultoria">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/linkedin.png" alt="" class="icon2_rod">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/o-email.png" alt="" class="icon2_rod">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://api.whatsapp.com/send?phone=5521966344698">
|
||||||
|
<img src="./Acessts/Imagens/Iconis/whatsapp (1).png" alt="" class="icon2_rod">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>A IT Guys possui a expertise necessária para criar uma solução capaz de atender a sua necessidade.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Coluna_Rod_2">
|
||||||
|
<div class="sub_coluna_Rod_2_1">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h2>Titulo</h2>
|
||||||
|
<ul>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Coluna_Rod_3">
|
||||||
|
<div class="sub_coluna_Rod_3_1">
|
||||||
|
<div>
|
||||||
|
<h2>Titulo</h2>
|
||||||
|
<ul>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Coluna_Rod_4">
|
||||||
|
<div class="sub_coluna_Rod_4_1">
|
||||||
|
<div>
|
||||||
|
<h2>Titulo</h2>
|
||||||
|
<ul>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
<a href="">
|
||||||
|
<li>Opição_1</li>
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<footer class="Bloco_Rodape2">
|
||||||
|
|
||||||
|
<h2>2024 ItGuys. Todos os direitos reservados</h2>
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue