#!/usr/bin/env python3
"""Check that a provisioned MinIO user can access only its own prefix."""

from __future__ import annotations

import os
import sys
from io import BytesIO

from minio import Minio
from minio.error import S3Error


def main() -> int:
    endpoint = _require("BEAVER_CHECK_MINIO_ENDPOINT")
    bucket = os.getenv("BEAVER_CHECK_MINIO_BUCKET", "beaver-user-files").strip()
    access_key = _require("BEAVER_CHECK_MINIO_ACCESS_KEY")
    secret_key = _require("BEAVER_CHECK_MINIO_SECRET_KEY")
    own_backend = _require("BEAVER_CHECK_MINIO_BACKEND_ID")
    other_backend = os.getenv("BEAVER_CHECK_MINIO_OTHER_BACKEND_ID", "policy-denied-other").strip()
    secure = os.getenv("BEAVER_CHECK_MINIO_SECURE", "0").strip().lower() in {"1", "true", "yes", "on"}

    client = Minio(endpoint, access_key=access_key, secret_key=secret_key, secure=secure)
    own_object = f"users/{own_backend}/uploads/policy-check.txt"
    other_object = f"users/{other_backend}/uploads/policy-check.txt"

    client.put_object(bucket, own_object, BytesIO(b"ok"), length=2, content_type="text/plain")
    client.stat_object(bucket, own_object)

    try:
        client.put_object(bucket, other_object, BytesIO(b"no"), length=2, content_type="text/plain")
    except S3Error as exc:
        if exc.code in {"AccessDenied", "AccessDeniedException"}:
            print(f"ok: {access_key} can access {own_object} and is denied for {other_object}")
            return 0
        raise

    print(f"error: {access_key} unexpectedly wrote {other_object}", file=sys.stderr)
    return 1


def _require(name: str) -> str:
    value = os.getenv(name, "").strip()
    if not value:
        raise SystemExit(f"{name} is required")
    return value


if __name__ == "__main__":
    raise SystemExit(main())
