Publish curated Unraid-AppOps-Gateway source from 68878c3167dacf2b424c16780e60e0d60815e477

This commit is contained in:
Public Source Publisher committed 2026-10-08 18:33:13 +00:00
1 parent 837c263cd8
commit 551de41e9f
18 files changed
+1183 -58

No files matched your search

+109
View File
@@ -33,6 +33,11 @@ from ..services.repopulse_adoption_journal import (
get_repopulse_adoption_status,
)
from ..services.user_access import current_user
from ..connectors.authentik import AuthentikConnector
from ..services.setup_service import apply_stored_connector_settings
from ..services.enrollment_oidc_settings import (
OIDC_TEMPLATE_SETTING_KEY, EnrollmentOidcProfileV1, load_profile, trusted_issuer_origin,
)
def _require_operator(request: Request) -> str:
@@ -225,6 +230,110 @@ def update_enrollment_storage_root(
return EnrollmentPlane.trust_status(session)
def _oidc_profile_status(session: Session):
apply_stored_connector_settings(session, {"authentik"})
profile = load_profile(session)
trust = EnrollmentPlane.get_trust_config(session)
matches = bool(profile and trust and profile.issuer == trusted_issuer_origin()
and AuthentikConnector.deployment_oidc_origin_matches(profile.issuer) and (
trust.oidc_issuer == profile.issuer
and trust.administrator_group == profile.administrator_group
and trust.support_agent_group == profile.support_agent_group
and trust.read_only_group == profile.read_only_group
))
return {"configured": matches, "issuerOrigin": trusted_issuer_origin(), "profile": profile.model_dump(mode="json") if profile else None}
@router.get("/trust/oidc-profile")
def enrollment_oidc_profile_status(session: EnrollmentSession, request: Request):
if current_user(request).role != "admin":
raise HTTPException(status_code=403, detail="Administrator role is required.")
return _oidc_profile_status(session)
@router.patch("/trust/oidc-profile")
def update_enrollment_oidc_profile(
payload: EnrollmentOidcProfileV1, session: EnrollmentSession, request: Request,
):
if current_user(request).role != "admin":
raise HTTPException(status_code=403, detail="Administrator role is required.")
if payload.issuer != trusted_issuer_origin():
raise HTTPException(status_code=409, detail="oidc_issuer_mismatch")
trust_row = session.get(AppSetting, TRUST_SETTING_KEY)
binding_row = session.get(AppSetting, OIDC_TEMPLATE_SETTING_KEY)
if trust_row is None or trust_row.is_secret:
raise HTTPException(status_code=409, detail="enrollment_trust_not_configured")
original = deepcopy(trust_row.value_json)
trust_updated_at = trust_row.updated_at
binding_original = deepcopy(binding_row.value_json) if binding_row else None
binding_updated_at = binding_row.updated_at if binding_row else None
if binding_row and binding_row.is_secret:
raise HTTPException(status_code=409, detail="oidc_profile_binding_invalid")
try:
updated = EnrollmentTrustConfigV1.model_validate({
**original,
"oidc_issuer": payload.issuer, "oidc_role_claim": "roles",
"administrator_group": payload.administrator_group,
"support_agent_group": payload.support_agent_group,
"read_only_group": payload.read_only_group,
})
except ValueError:
raise HTTPException(status_code=409, detail="enrollment_trust_changed") from None
apply_stored_connector_settings(session, {"authentik"})
connector = AuthentikConnector()
if not connector.deployment_oidc_origin_matches(payload.issuer):
raise HTTPException(status_code=409, detail="oidc_connector_issuer_mismatch")
connector.configure_deployment_oidc_template(payload.template_config(), issuer_origin=payload.issuer)
template = connector.validate_deployment_oidc_template(
role_claim="roles",
role_groups=(payload.administrator_group, payload.support_agent_group, payload.read_only_group),
)
if template.get("status") != "ready" or not connector.is_configured():
raise HTTPException(status_code=409, detail="oidc_profile_not_verified")
groups = connector.groups()
names = {str(g.get("name") or "") for g in groups.get("items", []) if isinstance(g, dict)}
if groups.get("success") is not True or not {payload.administrator_group, payload.support_agent_group, payload.read_only_group}.issubset(names):
raise HTTPException(status_code=409, detail="oidc_profile_not_verified")
value = payload.model_dump(mode="json")
try:
changed = session.execute(sql_update(AppSetting)
.where(AppSetting.key == TRUST_SETTING_KEY)
.where(AppSetting.updated_at == trust_updated_at)
.where(AppSetting.value_json == original)
.values(value_json=updated.model_dump(mode="json"), updated_at=utc_now())
.execution_options(synchronize_session=False))
if changed.rowcount != 1:
raise HTTPException(status_code=409, detail="enrollment_trust_changed")
if binding_row is None:
session.execute(sql_insert(AppSetting).values(
key=OIDC_TEMPLATE_SETTING_KEY, value_json=value, is_secret=False, updated_at=utc_now(),
))
else:
changed = session.execute(sql_update(AppSetting)
.where(AppSetting.key == OIDC_TEMPLATE_SETTING_KEY)
.where(AppSetting.updated_at == binding_updated_at)
.where(AppSetting.value_json == binding_original)
.values(value_json=value, updated_at=utc_now())
.execution_options(synchronize_session=False))
if changed.rowcount != 1:
raise HTTPException(status_code=409, detail="oidc_profile_changed")
log_event(session, source="settings", identity="manual",
action_id="enrollment.trust.oidc_profile.update", target="tower/deployment-controller",
risk="high", policy_decision="allowed", result="updated", target_type="controller",
reason="Administrator bound verified existing generic OIDC templates and three empty-or-existing role groups.",
before_state={"configured": binding_original is not None},
after_state={"configured": True, "issuer": payload.issuer},
)
except HTTPException:
session.rollback()
raise
except SQLAlchemyError:
session.rollback()
raise HTTPException(status_code=409, detail="oidc_profile_changed") from None
session.expire_all()
return _oidc_profile_status(session)
@router.post("")
def request_enrollment(
payload: EnrollmentRequestV1,