Publish curated Unraid-AppOps-Gateway source from 68878c3167dacf2b424c16780e60e0d60815e477
This commit is contained in:
1 parent
837c263cd8
commit
551de41e9f
18 files changed
+1183
-58
No files matched your search
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user