51 lines
1.7 KiB
Python
Executable File
51 lines
1.7 KiB
Python
Executable File
#!/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())
|