generated from coulomb/repo-seed
OpenCMIS in-memory server
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.error import HTTPError, URLError
|
||||
@@ -26,12 +28,29 @@ def run(context: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
timeout = _timeout_seconds(context)
|
||||
artifact_refs: list[str] = []
|
||||
credentials = _load_credentials(context)
|
||||
if credentials["status"] == "blocked":
|
||||
return {
|
||||
"result": "blocked",
|
||||
"observations": credentials["observations"],
|
||||
"facts": {
|
||||
"endpoint_found": True,
|
||||
"url": endpoint["url"],
|
||||
"blocked_reason": "credentials_unavailable",
|
||||
"auth_mode": credentials["auth_mode"],
|
||||
},
|
||||
"artifact_refs": [],
|
||||
}
|
||||
headers = {
|
||||
"Accept": "application/json, */*;q=0.1",
|
||||
"User-Agent": "guide-board-open-cmis-tck-preflight/0.1.0",
|
||||
}
|
||||
authorization = _authorization_header(credentials)
|
||||
if authorization is not None:
|
||||
headers["Authorization"] = authorization
|
||||
request = Request(
|
||||
endpoint["url"],
|
||||
headers={
|
||||
"Accept": "application/json, */*;q=0.1",
|
||||
"User-Agent": "guide-board-open-cmis-tck-preflight/0.1.0",
|
||||
},
|
||||
headers=headers,
|
||||
)
|
||||
try:
|
||||
with urlopen(request, timeout=timeout) as response:
|
||||
@@ -102,6 +121,7 @@ def run(context: dict[str, Any]) -> dict[str, Any]:
|
||||
"binding": endpoint["binding"],
|
||||
"http_status": status_code,
|
||||
"content_type": content_type,
|
||||
"auth_mode": credentials["auth_mode"],
|
||||
}
|
||||
|
||||
parsed = _parse_json(body)
|
||||
@@ -166,6 +186,83 @@ def _browser_endpoint(target: dict[str, Any]) -> dict[str, Any] | None:
|
||||
return None
|
||||
|
||||
|
||||
def _load_credentials(context: dict[str, Any]) -> dict[str, Any]:
|
||||
target = context["target_profile"]
|
||||
credentials_ref = target.get("credentials_ref")
|
||||
if not isinstance(credentials_ref, str) or not credentials_ref:
|
||||
return {"status": "available", "auth_mode": "anonymous"}
|
||||
if credentials_ref.startswith("env:"):
|
||||
return _load_env_credentials(credentials_ref)
|
||||
if credentials_ref.startswith("file:"):
|
||||
return _load_file_credentials(credentials_ref, context)
|
||||
return {
|
||||
"status": "blocked",
|
||||
"auth_mode": "unknown",
|
||||
"observations": [
|
||||
"Unsupported credentials_ref. Use env:USER_VAR,PASSWORD_VAR or file:/path/to/credentials.json."
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _load_env_credentials(credentials_ref: str) -> dict[str, Any]:
|
||||
names = credentials_ref.removeprefix("env:").split(",", 1)
|
||||
if len(names) != 2 or not names[0] or not names[1]:
|
||||
return {
|
||||
"status": "blocked",
|
||||
"auth_mode": "env",
|
||||
"observations": [
|
||||
"Environment credentials_ref must be env:USER_VAR,PASSWORD_VAR."
|
||||
],
|
||||
}
|
||||
user = os.environ.get(names[0])
|
||||
password = os.environ.get(names[1])
|
||||
missing = [name for name, value in [(names[0], user), (names[1], password)] if not value]
|
||||
if missing:
|
||||
return {
|
||||
"status": "blocked",
|
||||
"auth_mode": "env",
|
||||
"observations": [
|
||||
"Missing credential environment variable(s): " + ", ".join(missing) + "."
|
||||
],
|
||||
}
|
||||
return {"status": "available", "auth_mode": "env", "user": user, "password": password}
|
||||
|
||||
|
||||
def _load_file_credentials(credentials_ref: str, context: dict[str, Any]) -> dict[str, Any]:
|
||||
path = Path(credentials_ref.removeprefix("file:")).expanduser()
|
||||
if not path.is_absolute():
|
||||
target_path = context["plan"].get("profile_paths", {}).get("target_profile_path")
|
||||
if isinstance(target_path, str):
|
||||
path = Path(target_path).resolve().parent / path
|
||||
if not path.exists():
|
||||
return {
|
||||
"status": "blocked",
|
||||
"auth_mode": "file",
|
||||
"observations": [f"Credential file does not exist: {path}."],
|
||||
}
|
||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
||||
user = payload.get("user")
|
||||
password = payload.get("password")
|
||||
if not isinstance(user, str) or not isinstance(password, str):
|
||||
return {
|
||||
"status": "blocked",
|
||||
"auth_mode": "file",
|
||||
"observations": [
|
||||
"Credential file must contain string fields 'user' and 'password'."
|
||||
],
|
||||
}
|
||||
return {"status": "available", "auth_mode": "file", "user": user, "password": password}
|
||||
|
||||
|
||||
def _authorization_header(credentials: dict[str, Any]) -> str | None:
|
||||
user = credentials.get("user")
|
||||
password = credentials.get("password")
|
||||
if not isinstance(user, str) or not isinstance(password, str):
|
||||
return None
|
||||
token = base64.b64encode(f"{user}:{password}".encode("utf-8")).decode("ascii")
|
||||
return f"Basic {token}"
|
||||
|
||||
|
||||
def _timeout_seconds(context: dict[str, Any]) -> float:
|
||||
runtime_policy = context["assessment_profile"].get("runtime_policy", {})
|
||||
configured = runtime_policy.get("timeout_seconds", 5)
|
||||
|
||||
Reference in New Issue
Block a user