#!/usr/bin/env bash set -euo pipefail BASE_URL="${BASE_URL:-http://localhost:8888}" EMAIL="${EMAIL:-admin@example.com}" PASSWORD="${PASSWORD:-admin123}" STUDY_ID="${STUDY_ID:-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}" echo "[1/6] login: $EMAIL" TOKEN=$(BASE_URL="$BASE_URL" EMAIL="$EMAIL" PASSWORD="$PASSWORD" python3 - <<'PY' import base64 import json import os import urllib.request from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.ciphers.aead import AESGCM base_url = os.environ["BASE_URL"] email = os.environ["EMAIL"] password = os.environ["PASSWORD"] with urllib.request.urlopen(f"{base_url}/api/v1/auth/login-key", timeout=20) as resp: login_key = json.loads(resp.read().decode()) public_key = serialization.load_pem_public_key(login_key["public_key"].encode("utf-8")) plaintext = json.dumps( {"email": email, "password": password, "challenge": login_key["challenge"]}, separators=(",", ":"), ).encode("utf-8") aes_key = AESGCM.generate_key(bit_length=256) iv = os.urandom(12) encrypted_data = AESGCM(aes_key).encrypt(iv, plaintext, None) encrypted_key = public_key.encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None, ), ) payload = json.dumps( { "key_id": login_key["key_id"], "challenge": login_key["challenge"], "ciphertext": base64.b64encode( json.dumps( { "encrypted_key": base64.b64encode(encrypted_key).decode("ascii"), "iv": base64.b64encode(iv).decode("ascii"), "data": base64.b64encode(encrypted_data).decode("ascii"), }, separators=(",", ":"), ).encode("utf-8") ).decode("ascii"), } ).encode() req = urllib.request.Request( f"{base_url}/api/v1/auth/login", method="POST", headers={"Content-Type": "application/json"}, data=payload, ) with urllib.request.urlopen(req, timeout=20) as resp: print(json.loads(resp.read().decode()).get("access_token", "")) PY ) if [[ -z "$TOKEN" ]]; then echo "login failed: access_token empty" exit 1 fi AUTH=(-H "Authorization: Bearer $TOKEN") echo "[2/6] get setup-config" GET_RESP=$(curl -sS "$BASE_URL/api/v1/studies/$STUDY_ID/setup-config" "${AUTH[@]}") VERSION=$(echo "$GET_RESP" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("version",""))') if [[ -z "$VERSION" ]]; then echo "get setup-config failed" echo "$GET_RESP" exit 1 fi echo "version=$VERSION" echo "[3/6] save draft" PUT_PAYLOAD=$(cat <