diff --git a/Insurance/StahováníSeznamuPojištěnců/207 OZP/StahniSeznamPojistencuOZP.py b/Insurance/StahováníSeznamuPojištěnců/207 OZP/StahniSeznamPojistencuOZP.py new file mode 100644 index 0000000..000a1a0 --- /dev/null +++ b/Insurance/StahováníSeznamuPojištěnců/207 OZP/StahniSeznamPojistencuOZP.py @@ -0,0 +1,105 @@ +""" +Stahování seznamu registrovaných pojištěnců OZP (207) — čistý Python. + +OZP běží na stejné platformě jako ZPŠ (portalzp.cz / json-api). +Tento skript zatím umí jen KROK 1: přihlášení certifikátem. + +Stavba poběží postupně: + [krok 1] přihlášení certifikátem ← hotovo + [krok 2] stažení nových výpisů ze schránky + [krok 3] podání žádosti o další měsíc +""" + +import json +import os +import sys + +import requests +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.serialization import pkcs7, pkcs12 + +PFX_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Certificates", "MBQualifiedCert.pfx")) +PFX_PASSWORD = b"Vlado7309208104++" + +BASE_URL = "https://portal.ozp.cz" +CHALLENGE_URL = f"{BASE_URL}/json-api/prihlaseni/prihlasovaci-zprava" +CERTLOGIN_URL = f"{BASE_URL}/json-api/prihlaseni/prihlaseni-certifikatem" + +# Sdílený cookies soubor s OZP skriptem pro stahování zpráv +COOKIES_FILE = os.path.abspath(os.path.join( + os.path.dirname(__file__), "..", "..", "StahováníZpráv", "207 OZP", "ozp_cookies.json" +)) + + +def prihlaseni() -> requests.Session: + """Přihlásí se certifikátem, vrátí autentizovanou session. Uloží cookies pro Playwright.""" + session = requests.Session() + session.headers.update({ + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "X-Requested-With": "XMLHttpRequest", + "Origin": BASE_URL, + "Referer": BASE_URL + "/", + }) + + # 1. Načti login stránku → session cookie + r = session.get(f"{BASE_URL}/app/prihlaseni") + r.raise_for_status() + session.cookies.set("pzp_sign", "CERT", domain="portal.ozp.cz", path="/") + + # 2. Získej challenge + r = session.post(CHALLENGE_URL, json={"login_sign": "CERT"}, + headers={"Content-Type": "application/json; charset=UTF-8"}) + r.raise_for_status() + zprava = r.json()["data"]["zprava"] + print(f"Challenge: {zprava[:60]}...") + + # 3. Podepiš challenge certifikátem (PKCS7 detached, RSA + SHA-256, s certifikátem) + with open(PFX_PATH, "rb") as f: + private_key, cert, _ = pkcs12.load_key_and_certificates(f.read(), PFX_PASSWORD) + + podpis = ( + pkcs7.PKCS7SignatureBuilder() + .set_data(zprava.encode("utf-8")) + .add_signer(cert, private_key, hashes.SHA256()) + .sign(serialization.Encoding.PEM, [pkcs7.PKCS7Options.DetachedSignature]) + .decode("ascii").strip() + ) + + # 4. Přihlas se + r = session.post(CERTLOGIN_URL, json={"zprava": zprava, "podpis": podpis}, + headers={"Content-Type": "application/json; charset=UTF-8"}) + r.raise_for_status() + data = r.json()["data"] + + if not data.get("prihlasen"): + raise RuntimeError(f"Přihlášení selhalo: {r.json().get('errMsg', '')}") + + print(f"Přihlášení úspěšné! {data.get('url', '')}") + + # 5. Ulož cookies pro Playwright + cookies = [ + { + "name": c.name, + "value": c.value, + "domain": c.domain if c.domain.startswith(".") else "." + c.domain, + "path": c.path or "/", + "expires": int(c.expires) if c.expires else -1, + "secure": bool(c.secure), + "httpOnly": False, + "sameSite": "Lax", + } + for c in session.cookies + ] + with open(COOKIES_FILE, "w", encoding="utf-8") as f: + json.dump(cookies, f, indent=2, ensure_ascii=False) + print(f"Cookies uloženy: {len(cookies)} → {COOKIES_FILE}") + + return session + + +def hlavni() -> None: + prihlaseni() + + +if __name__ == "__main__": + hlavni()