Přidej POSTUP.md — dokumentace VoZP přihlášení a stahování
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,146 @@
|
|||||||
|
# VoZP — Automatické stahování zpráv
|
||||||
|
|
||||||
|
## Co to dělá
|
||||||
|
|
||||||
|
Dva skripty které se přihlásí na portál VoZP a stáhnou všechny zprávy ze schránek:
|
||||||
|
|
||||||
|
1. `01_prihlaseni.py` — přihlásí se certifikátem, uloží cookies do `vozp_cookies.json`
|
||||||
|
2. `02_stahuj_vse.py` — použije cookies, projde všechny schránky, stáhne soubory do `Staženo/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Jak funguje přihlášení (challenge-response)
|
||||||
|
|
||||||
|
Portál **nepoužívá heslo** — autentizuje certifikátem přes 4 kroky:
|
||||||
|
|
||||||
|
### Krok 1 — Získej session
|
||||||
|
```
|
||||||
|
GET https://portal.vozp.cz/app/prihlaseni
|
||||||
|
→ server nastaví cookie: SID=...
|
||||||
|
```
|
||||||
|
Ručně nastav cookie: `pzp_sign=CERT` (říká serveru, že chceš certifikát)
|
||||||
|
|
||||||
|
### Krok 2 — Získej challenge
|
||||||
|
```
|
||||||
|
POST /json-api/prihlaseni/prihlasovaci-zprava
|
||||||
|
Body: {"login_sign": "CERT"}
|
||||||
|
|
||||||
|
Odpověď:
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"zprava": "Prohlášení:\r\nTímto se přihlašuji k Portálu VOZP ČR\r\n\r\nOkamžik vygenerování ... mikrosekundu: 20.04.2026 13:22:34.058119"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Krok 3 — Podepis certifikátem
|
||||||
|
Zprávu z kroku 2 podepíš jako **PKCS7 / CMS SignedData**:
|
||||||
|
- Algoritmus: **RSA + SHA-256**
|
||||||
|
- Typ: **DetachedSignature** (obsah není vložen do podpisu)
|
||||||
|
- **BEZ CA řetězu** — pouze end-entity certifikát, žádné CA certifikáty
|
||||||
|
|
||||||
|
```python
|
||||||
|
podpis = (
|
||||||
|
pkcs7.PKCS7SignatureBuilder()
|
||||||
|
.set_data(zprava.encode("utf-8"))
|
||||||
|
.add_signer(cert, private_key, hashes.SHA256())
|
||||||
|
.sign(Encoding.PEM, [PKCS7Options.DetachedSignature])
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ Přidání CA řetězu způsobí chybu "neznámý klientský certifikát" — i když thumbprint sedí!
|
||||||
|
|
||||||
|
### Krok 4 — Přihlášení
|
||||||
|
```
|
||||||
|
POST /json-api/prihlaseni/prihlaseni-certifikatem
|
||||||
|
Body: {
|
||||||
|
"zprava": "<původní challenge text>",
|
||||||
|
"podpis": "-----BEGIN PKCS7-----\n...\n-----END PKCS7-----"
|
||||||
|
}
|
||||||
|
|
||||||
|
Úspěch: {"data": {"prihlasen": true, "url": "/app/uvodni-stranka"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Certifikát
|
||||||
|
|
||||||
|
| Položka | Hodnota |
|
||||||
|
|---|---|
|
||||||
|
| Soubor | `U:\ordinaceprojekt\Insurance\Certificates\MBQualifiedCert.pfx` |
|
||||||
|
| Vlastník | MUDr. Michaela Buzalková |
|
||||||
|
| Vydavatel | I.CA EU Qualified CA2/RSA 06/2022 |
|
||||||
|
| Platnost | do 2027-01-16 |
|
||||||
|
| Thumbprint | `056ED80A3CDDE31DD36EECE0181B4E78D61122A7` |
|
||||||
|
| Serial (hex) | `0247068517B0049E2E` |
|
||||||
|
|
||||||
|
Jak exportovat správný certifikát z Windows:
|
||||||
|
```powershell
|
||||||
|
# Najdi certifikát podle thumbprintu
|
||||||
|
$cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq "056ED80A3CDDE31DD36EECE0181B4E78D61122A7"}
|
||||||
|
$pwd = Read-Host "Heslo" -AsSecureString
|
||||||
|
Export-PfxCertificate -Cert $cert -FilePath "MBQualifiedCert.pfx" -Password $pwd
|
||||||
|
```
|
||||||
|
|
||||||
|
> Při exportu: PKCS #12, **nezaškrtávej** "Include all certificates in the certification path"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stahování souborů
|
||||||
|
|
||||||
|
`02_stahuj_vse.py` používá **Playwright** (viditelný Chrome) pro navigaci + `context.request.get()` pro stahování.
|
||||||
|
|
||||||
|
Endpoint stahování:
|
||||||
|
```
|
||||||
|
GET /html/prehled-zprav-ve-schrankach/zobrazit-prilohu?zprava_id={id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schránky které se prochází
|
||||||
|
|
||||||
|
| Segment URL | Název |
|
||||||
|
|---|---|
|
||||||
|
| `171-schranka-poskytovatele-zdravotnich-sluzeb` | Schránka PZS |
|
||||||
|
| `183-schranka-klientu-portalu` | Schránka klientů portálu |
|
||||||
|
| `185-schranka-pzs` | Schránka PZS2 |
|
||||||
|
| `187-schranka-klienta` | Schránka klienta |
|
||||||
|
| `198-vypis-registrovanych-pacientu` | Výpis registrovaných pacientů |
|
||||||
|
| `200-zuctovaci-zpravy` | Zúčtovací zprávy |
|
||||||
|
| `205-vypis-osobnich-uctu-pojistencu` | Výpis osobních účtů pojištěnců |
|
||||||
|
|
||||||
|
### Paginace — důležité
|
||||||
|
|
||||||
|
Portál při přetečení stránek (např. stranka-16 když existuje jen 15) **vrátí poslední stránku znovu** místo prázdné. Detekce: sleduj `fileId` napříč stránkami, zastav při opakování.
|
||||||
|
|
||||||
|
```python
|
||||||
|
current_ids = {r["fileId"] for r in rows}
|
||||||
|
if current_ids & seen_ids:
|
||||||
|
break # opakující se obsah = konec
|
||||||
|
seen_ids.update(current_ids)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pojmenování stažených souborů
|
||||||
|
|
||||||
|
```
|
||||||
|
YYYY-MM-DD Popis zprávy (původní_název_souboru).přípona
|
||||||
|
```
|
||||||
|
Příklad: `2026-04-15 Odpověď na podání č. 176867777 (Protokol-OK).html`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Závislosti
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install requests cryptography playwright
|
||||||
|
playwright install chrome
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spuštění
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python 01_prihlaseni.py # přihlásí, uloží cookies
|
||||||
|
python 02_stahuj_vse.py # stáhne vše nové
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user