diff --git a/extranet_token.py b/extranet_token.py new file mode 100644 index 0000000..7f22ad7 --- /dev/null +++ b/extranet_token.py @@ -0,0 +1,303 @@ +import os +import hashlib +import base64 +import requests +import re +import json +from datetime import datetime +import pyodbc +import time + + + +hoje_coluna = datetime.today() # Pegando a Data e Hora de hoje +hoje_formatado = hoje_coluna.strftime('%Y-%m-%d') +data_atual = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + +# Constantes de tempo em segundos +TEMPO_ESPERA_SUCESSO = 45 * 60 # 45 minutos +TEMPO_ESPERA_ERRO = 3 * 60 # 3 minutos + +def generate_code_verifier(): + """Gera um code_verifier aleatório.""" + return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip("=") + +def generate_code_challenge(code_verifier): + """Gera o code_challenge usando SHA-256.""" + sha256_hash = hashlib.sha256(code_verifier.encode('utf-8')).digest() + return base64.urlsafe_b64encode(sha256_hash).decode('utf-8').rstrip("=") + +def send_authorization_request(session, code_challenge): + """Envia uma requisição GET para a página de login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD", + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "response_type": "code", + "scope": "openid email https://gboticariob2c.onmicrosoft.com/a6cd4fe6-3d71-455a-b99d-f458a07cc0d1/extranet.api offline_access", + "state": "15d9d7f95f8648d1941426f4665aa383", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "response_mode": "query" + } + + response = session.get(url, params=params) + if response.status_code == 200: + print("Página de login carregada com sucesso.") + return response.text # Retorna o HTML + else: + print(f"Erro ao acessar a página de login: {response.status_code}") + print("Resposta de erro:", response.text) + return None + +def extract_tokens(html_content): + """Extrai o CSRF Token e StateProperties do conteúdo HTML.""" + csrf_token = None + state_properties = None + + if html_content: + csrf_match = re.search(r'"csrf":"(.*?)"', html_content) + csrf_token = csrf_match.group(1) if csrf_match else None + + state_properties_match = re.search(r'"transId":"StateProperties=(.*?)"', html_content) + state_properties = state_properties_match.group(1) if state_properties_match else None + + return csrf_token, state_properties + +def send_login_request(session, csrf_token, state_properties, username, password): + """Envia uma requisição POST para realizar o login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/SelfAsserted" + + params = { + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FEDCorp_APIGEE_PRD" + } + + headers = { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-CSRF-TOKEN": csrf_token, + "X-Requested-With": "XMLHttpRequest", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "application/json, text/javascript, */*; q=0.01", + "Origin": "https://login.extranet.grupoboticario.com.br", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + data = { + "request_type": "RESPONSE", + "signInName": username, + "password": password + } + + response = session.post(url, params=params, headers=headers, data=data) + if response.status_code == 200: + print("Login realizado com sucesso!") + return response.text + else: + print(f"Erro ao realizar login: {response.status_code}") + return None + +def send_final_request(session, csrf_token, state_properties): + """ + Envia a última requisição GET para obter a página HTML. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/api/CombinedSigninAndSignup/confirmed" + + params = { + "rememberMe": "false", + "csrf_token": csrf_token, + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD" + } + + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + response = session.get(url, headers=headers, params=params, allow_redirects=False) + if response.status_code == 200: + print("Requisição final bem-sucedida!") + return response.text # Retorna o HTML + else: + print(f"Erro na requisição final: {response.status_code}") + return response.text + +def extract_code_from_html(html_content): + """ + Extrai o valor do parâmetro `code` da URL no HTML fornecido. + + :param html_content: O conteúdo HTML como string. + :return: O valor do código ou None, se não encontrado. + """ + # Regex para encontrar o parâmetro `code` na URL do atributo `href` + match = re.search(r'href="[^"]*?code=([^&"]+)', html_content) + if match: + return match.group(1) # Captura o valor do parâmetro `code` + return match + +def send_token_request(code, code_verifier): + """ + Envia uma requisição POST para obter o token usando o código e o code_verifier. + + :param code: O código extraído da etapa anterior. + :param code_verifier: O code_verifier usado no início do fluxo. + :return: A resposta do servidor. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/token" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD" + } + + headers = { + "Host": "login.extranet.grupoboticario.com.br", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "*/*", + "Origin": "https://extranet.grupoboticario.com.br", + "Sec-Fetch-Site": "same-site", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Dest": "empty", + "Referer": "https://extranet.grupoboticario.com.br/", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + } + + data = { + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "code": code, + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "code_verifier": code_verifier, + "grant_type": "authorization_code" + } + + response = requests.post(url, params=params, headers=headers, data=data) + return response.text + + +def extract_tokens_2(response_1): + response = json.loads(response_1) + try: + access_token = response.get("access_token") + id_token = response.get("id_token") + refresh_token = response.get("refresh_token") + + return { + "access_token": access_token, + "id_token": id_token, + "refresh_token": refresh_token + } + except Exception as e: + print(f"Erro ao extrair tokens: {e}") + return None + + +def insert_token_to_db(token): + """ + Insere o token no banco de dados SQL Server + """ + try: + conn = pyodbc.connect( + 'DRIVER={ODBC Driver 18 for SQL Server};' + 'SERVER=10.77.77.10;' + 'DATABASE=GINSENG;' + 'UID=supginseng;' + 'PWD=Iphone2513@;' + 'PORT=1433;' + 'TrustServerCertificate=yes' + ) + cursor = conn.cursor() + + # Limpar a tabela antes de inserir + truncate_sql = "TRUNCATE TABLE [GINSENG].[dbo].[tokens]" + cursor.execute(truncate_sql) + conn.commit() + print("Tabela limpa com sucesso!") + + # Adicionar prefixo Bearer ao token + token_with_bearer = f"Bearer {token}" + + # Inserir o novo token + sql = "INSERT INTO [GINSENG].[dbo].[tokens] (token, created_at, updated_at) VALUES (?, GETDATE(), GETDATE())" + cursor.execute(sql, token_with_bearer) + conn.commit() + + print("Token inserido com sucesso no banco de dados!") + + cursor.close() + conn.close() + + except Exception as e: + print(f"Erro ao inserir token no banco de dados: {e}") + +def main_loop(): + """ + Função principal que executa em loop, controlando os tempos de espera + """ + while True: + try: + print(f"\n[{datetime.now()}] Iniciando processo de obtenção do token...") + + session = requests.Session() + code_verifier = generate_code_verifier() + code_challenge = generate_code_challenge(code_verifier) + + # Enviar requisição GET para obter tokens + html_content = send_authorization_request(session, code_challenge) + csrf_token, state_properties = extract_tokens(html_content) + + if not csrf_token or not state_properties: + print(f"[{datetime.now()}] Falha ao extrair CSRF Token ou StateProperties.") + print(f"Aguardando {TEMPO_ESPERA_ERRO/60} minutos antes de tentar novamente...") + time.sleep(TEMPO_ESPERA_ERRO) + continue + + # Dados de login + username = "daniel.rodrigue" + password = "Iphone2513@" + + # Enviar requisição POST para login + login_response = send_login_request(session, csrf_token, state_properties, username, password) + + if not login_response: + print(f"[{datetime.now()}] Falha no login.") + print(f"Aguardando {TEMPO_ESPERA_ERRO/60} minutos antes de tentar novamente...") + time.sleep(TEMPO_ESPERA_ERRO) + continue + + # Enviar requisição final + final_page_html = send_final_request(session, csrf_token, state_properties) + code = extract_code_from_html(final_page_html) + + if not code: + print(f"[{datetime.now()}] Falha ao extrair código.") + print(f"Aguardando {TEMPO_ESPERA_ERRO/60} minutos antes de tentar novamente...") + time.sleep(TEMPO_ESPERA_ERRO) + continue + + token = send_token_request(code, code_verifier) + tokens = extract_tokens_2(token) + + if tokens: + access_token = tokens["access_token"] + insert_token_to_db(access_token) + print(f"[{datetime.now()}] Token obtido e salvo com sucesso!") + print(f"Aguardando {TEMPO_ESPERA_SUCESSO/60} minutos antes da próxima atualização...") + time.sleep(TEMPO_ESPERA_SUCESSO) + else: + print(f"[{datetime.now()}] Falha ao processar tokens.") + print(f"Aguardando {TEMPO_ESPERA_ERRO/60} minutos antes de tentar novamente...") + time.sleep(TEMPO_ESPERA_ERRO) + + except Exception as e: + print(f"[{datetime.now()}] Erro inesperado: {str(e)}") + print(f"Aguardando {TEMPO_ESPERA_ERRO/60} minutos antes de tentar novamente...") + time.sleep(TEMPO_ESPERA_ERRO) + +if __name__ == "__main__": + main_loop() + +