From d40368e71f0039d19569e0195e7c4455fb213617 Mon Sep 17 00:00:00 2001 From: nix Date: Fri, 7 Nov 2025 19:35:35 +0000 Subject: [PATCH] initial commit --- berretin.py | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tokenext.py | 62 ++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 berretin.py create mode 100644 tokenext.py diff --git a/berretin.py b/berretin.py new file mode 100644 index 0000000..66878b8 --- /dev/null +++ b/berretin.py @@ -0,0 +1,107 @@ +import os +import hashlib +import json +import requests +import subprocess +from datetime import datetime, timedelta +from flask import Flask, jsonify, Response, request + +BASE_API = "https://ws1.smn.gob.ar" +CACHE_DIR = "json.api.cache" +CACHE_TTL = timedelta(minutes=30) +SMN_TOKEN_FILE = "token.txt" +ACCESS_TOKEN = "i.hate.smn" + +app = Flask(__name__) + +def get_cache_filename(url: str) -> str: + h = hashlib.sha256(url.encode()).hexdigest() + return os.path.join(CACHE_DIR, f"{h}.json") + +def load_cache(url: str): + path = get_cache_filename(url) + if not os.path.exists(path): + return None + mtime = datetime.fromtimestamp(os.path.getmtime(path)) + if datetime.now() - mtime > CACHE_TTL: + return None + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + +def save_cache(url: str, data: dict): + os.makedirs(CACHE_DIR, exist_ok=True) + path = get_cache_filename(url) + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2, ensure_ascii=False) + +def load_smn_token(): + with open(SMN_TOKEN_FILE, "r") as f: + return f.read().strip() + +def refresh_smn_token(): + print("[TOKEN] Refreshing SMN token...") + try: + result = subprocess.run( + ["python3", "tokenext.py"], # cheap as fuck, fixing later + capture_output=True, + text=True, + timeout=60 + ) + if result.returncode == 0: + print("[TOKEN] Token refreshed successfully.") + else: + print("[TOKEN] Failed to refresh token:", result.stderr) + except Exception as e: + print("[TOKEN] Error running tokenext.py:", e) + +def check_access_token(): + header_token = request.headers.get("Authorization", "").strip() + return header_token == ACCESS_TOKEN + +def fetch_from_smn(url: str, retry: bool = True): + token = load_smn_token() + headers = { + "Authorization": f"JWT {token}", + "Accept": "application/json", + "User-Agent": "Mozilla/5.0" + } + + resp = requests.get(url, headers=headers) + + if resp.status_code == 401 and retry: + print("[AUTH] SMN token expired, trying to refresh...") + refresh_smn_token() + return fetch_from_smn(url, retry=False) + + return resp + +@app.route("/smn/") +def smn_proxy(subpath): + if not check_access_token(): + return jsonify({"error": "Unauthorized"}), 401 + + url = f"{BASE_API}/{subpath}" + + # Check cache + cached = load_cache(url) + if cached: + print(f"[CACHE] Loaded {subpath}") + return jsonify(cached) + + print(f"[FETCH] {url}") + resp = fetch_from_smn(url) + + if resp.status_code != 200: + return Response( + resp.text, + status=resp.status_code, + content_type=resp.headers.get("Content-Type", "text/plain") + ) + + data = resp.json() + save_cache(url, data) + return jsonify(data) + +if __name__ == "__main__": + os.makedirs(CACHE_DIR, exist_ok=True) + app.run(host="0.0.0.0", port=8080, debug=False) diff --git a/tokenext.py b/tokenext.py new file mode 100644 index 0000000..88bec5b --- /dev/null +++ b/tokenext.py @@ -0,0 +1,62 @@ +import re +import time +from selenium import webdriver +from selenium.webdriver.chrome.options import Options +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + +URL = "https://www.smn.gob.ar/" +OUTPUT_FILE = "token.txt" + +def extract_token_from_source(source: str): + m = re.search(r"localStorage\.setItem\(\s*['\"]token['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)", source) + return m.group(1) if m else None + +chrome_options = Options() +chrome_options.add_argument("--headless=new") +chrome_options.add_argument("--no-sandbox") +chrome_options.add_argument("--disable-dev-shm-usage") +chrome_options.add_argument("--disable-gpu") +chrome_options.add_argument("--disable-blink-features=AutomationControlled") +chrome_options.add_argument("--window-size=1920,1080") +chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/118.0.5993.90 Safari/537.36") + +driver = webdriver.Chrome(options=chrome_options) + +try: + print(f"Loading URL {URL}") + driver.get(URL) + + time.sleep(8) + + try: + WebDriverWait(driver, 20).until( + EC.presence_of_element_located((By.TAG_NAME, "body")) + ) + except Exception: + pass + + try: + token = driver.execute_script("return window.localStorage.getItem('token');") + except Exception: + token = None + + if not token: + token = extract_token_from_source(driver.page_source) + + if token: + print(f"\n[+] Token found:\n{token}\n") + with open(OUTPUT_FILE, "w", encoding="utf-8") as f: + f.write(token) + print(f"[+] Saved to {OUTPUT_FILE}") + else: + print("[!] No token found in localStorage or page source.") + with open("page_debug.html", "w", encoding="utf-8") as f: + f.write(driver.page_source) + print("[i] Saved full page source to page_debug.html for manual check.") + +finally: + driver.quit()