Initial curated Unraid-AppOps-Gateway source from 3bd6f6fee310125bfbb4d4650389a817f498724d
This commit is contained in:
commit
1dfbca08a1
528 files changed
+131054
No files matched your search
@@ -0,0 +1,96 @@
|
||||
"""One durable credential for the fixed RepoPulse legacy adoption target."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
import secrets
|
||||
|
||||
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlmodel import Session
|
||||
|
||||
from ..core.time import utc_now
|
||||
from ..db.models import Secret
|
||||
from . import secret_store
|
||||
|
||||
_INTENT_ID = re.compile(r"^rpa-[0-9a-f]{20}$")
|
||||
_REF = "ENROLL_REPOPULSE_TARGET_HMAC"
|
||||
|
||||
|
||||
class RepoPulseTargetCredentialError(RuntimeError):
|
||||
"""A sanitized fixed-target credential error."""
|
||||
|
||||
|
||||
def get_or_create_repopulse_target_credential(
|
||||
session: Session, *, intent_id: str
|
||||
) -> tuple[str, bytes]:
|
||||
"""Insert once, then reuse the encrypted credential on every retry.
|
||||
|
||||
The caller must have durably reserved the same adoption intent before this
|
||||
method is called. The plaintext is returned only to the in-process private
|
||||
TLS client and must never be added to a receipt, response, or log.
|
||||
"""
|
||||
if not isinstance(intent_id, str) or _INTENT_ID.fullmatch(intent_id) is None:
|
||||
raise RepoPulseTargetCredentialError("adoption_intent_invalid")
|
||||
if secret_store.secret_storage_status().get("productionReady") is not True:
|
||||
raise RepoPulseTargetCredentialError("secret_store_not_ready")
|
||||
|
||||
enrollment_id = f"enr-{intent_id.removeprefix('rpa-')}"
|
||||
candidate = secrets.token_urlsafe(48)
|
||||
metadata = {
|
||||
"intentId": intent_id,
|
||||
"enrollmentId": enrollment_id,
|
||||
"rotationState": "active",
|
||||
"credentialFingerprint": hashlib.sha256(candidate.encode("ascii")).hexdigest()[
|
||||
:16
|
||||
],
|
||||
}
|
||||
now = utc_now()
|
||||
try:
|
||||
session.execute(
|
||||
sqlite_insert(Secret)
|
||||
.values(
|
||||
id=_REF,
|
||||
name=_REF,
|
||||
encrypted_value=secret_store._fernet()
|
||||
.encrypt(candidate.encode("ascii"))
|
||||
.decode("ascii"),
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
used_by_json=[f"enrollment:{enrollment_id}", "deployment-controller"],
|
||||
metadata_json=metadata,
|
||||
)
|
||||
.on_conflict_do_nothing(index_elements=[Secret.id])
|
||||
)
|
||||
session.commit()
|
||||
row = session.get(Secret, _REF, populate_existing=True)
|
||||
if (
|
||||
row is None
|
||||
or row.name != _REF
|
||||
or not isinstance(row.metadata_json, dict)
|
||||
or row.metadata_json.get("intentId") != intent_id
|
||||
or row.metadata_json.get("enrollmentId") != enrollment_id
|
||||
):
|
||||
raise RepoPulseTargetCredentialError("target_credential_collision")
|
||||
value = secret_store.get_secret(session, _REF, touch=False)
|
||||
if (
|
||||
not value
|
||||
or not 32 <= len(value) <= 256
|
||||
or not value.isascii()
|
||||
or not value.isprintable()
|
||||
):
|
||||
raise RepoPulseTargetCredentialError("target_credential_unavailable")
|
||||
if (
|
||||
row.metadata_json.get("credentialFingerprint")
|
||||
!= hashlib.sha256(value.encode("utf-8")).hexdigest()[:16]
|
||||
):
|
||||
raise RepoPulseTargetCredentialError(
|
||||
"target_credential_fingerprint_mismatch"
|
||||
)
|
||||
return enrollment_id, value.encode("utf-8")
|
||||
except SQLAlchemyError:
|
||||
session.rollback()
|
||||
raise RepoPulseTargetCredentialError(
|
||||
"target_credential_storage_unavailable"
|
||||
) from None
|
||||
Reference in new issue
Block a user