Compare commits
1 changed files with 8 additions and 24 deletions
|
|
@ -28,12 +28,6 @@ const CORE_AVATAR_MARKER: &str = "/var/lib/hyperhive/forge-core-avatar-set";
|
||||||
/// Sibling marker for the `agent-configs` org avatar. Same one-shot
|
/// Sibling marker for the `agent-configs` org avatar. Same one-shot
|
||||||
/// semantics — delete to force the upload to re-run.
|
/// semantics — delete to force the upload to re-run.
|
||||||
const CONFIG_ORG_AVATAR_MARKER: &str = "/var/lib/hyperhive/forge-agent-configs-avatar-set";
|
const CONFIG_ORG_AVATAR_MARKER: &str = "/var/lib/hyperhive/forge-agent-configs-avatar-set";
|
||||||
/// Per-agent marker written once the account email has been aligned to
|
|
||||||
/// `{name}@hyperhive`. Skips the `PATCH /api/v1/admin/users/{name}`
|
|
||||||
/// call on every subsequent `sync_agent` tick — that PATCH was resetting
|
|
||||||
/// Forgejo's `use_custom_avatar` flag and clobbering the avatar uploaded
|
|
||||||
/// by `forge-avatar-sync`. Delete to force re-alignment.
|
|
||||||
const EMAIL_ALIGNED_MARKER_PREFIX: &str = "/var/lib/hyperhive/forge-email-aligned-";
|
|
||||||
// Avatar PNGs are loaded at runtime from
|
// Avatar PNGs are loaded at runtime from
|
||||||
// `$HIVE_ASSETS_DIR/branding/{hyperhive,agent-configs}.png` via the
|
// `$HIVE_ASSETS_DIR/branding/{hyperhive,agent-configs}.png` via the
|
||||||
// helpers in `hive_sh4re::assets`. The `agent-configs.png` is
|
// helpers in `hive_sh4re::assets`. The `agent-configs.png` is
|
||||||
|
|
@ -237,37 +231,27 @@ async fn change_user_password(name: &str, password: &str) -> Result<()> {
|
||||||
|
|
||||||
/// Idempotently align the Forgejo account email to `agent_email(name)`.
|
/// Idempotently align the Forgejo account email to `agent_email(name)`.
|
||||||
/// Existing agents were created with `{name}@hive.local`; this corrects
|
/// Existing agents were created with `{name}@hive.local`; this corrects
|
||||||
/// that so git commits (which use `{name}@hyperhive`) link to profiles.
|
/// that so git commits (which use `{name}@hyperhive.local`) link to profiles.
|
||||||
/// Best-effort: failures are warned, not propagated.
|
/// Best-effort: failures are warned, not propagated.
|
||||||
///
|
///
|
||||||
/// Marker-guarded: writes `EMAIL_ALIGNED_MARKER_PREFIX{name}` on first
|
|
||||||
/// success and skips the PATCH on all subsequent calls. This prevents
|
|
||||||
/// Forgejo's admin-user-edit endpoint from resetting `use_custom_avatar`
|
|
||||||
/// on every `sync_agent` tick. Delete the marker to force re-alignment.
|
|
||||||
///
|
|
||||||
/// Uses the admin REST API (`PATCH /api/v1/admin/users/{name}`) rather
|
/// Uses the admin REST API (`PATCH /api/v1/admin/users/{name}`) rather
|
||||||
/// than `forgejo admin user edit` because the CLI dropped the `edit`
|
/// than `forgejo admin user edit` because the CLI dropped the `edit`
|
||||||
/// subcommand somewhere between forgejo 8 and current. Body includes
|
/// subcommand somewhere between forgejo 8 and current (the bare CLI
|
||||||
/// `login_name` (required by Forgejo's `EditUserOption` validator) and
|
/// surfaced as "flag provided but not defined: -username"). Body sets
|
||||||
/// `source_id = 0` (local auth, the default for users hive-c0re creates).
|
/// `source_id = 0` (local auth, the default for users hive-c0re
|
||||||
|
/// creates) which forgejo's PATCH validator requires even when the
|
||||||
|
/// only thing changing is the email.
|
||||||
async fn ensure_user_email(name: &str) {
|
async fn ensure_user_email(name: &str) {
|
||||||
let marker = format!("{EMAIL_ALIGNED_MARKER_PREFIX}{name}");
|
|
||||||
if std::path::Path::new(&marker).exists() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let Some(token) = core_token() else {
|
let Some(token) = core_token() else {
|
||||||
tracing::debug!(%name, "forge: skipping ensure_user_email — no core token yet");
|
tracing::debug!(%name, "forge: skipping ensure_user_email — no core token yet");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let email = agent_email(name);
|
let email = agent_email(name);
|
||||||
// `login_name` is required by Forgejo's EditUserOption validator.
|
let body = format!(r#"{{"email":"{email}","source_id":0}}"#);
|
||||||
// Omitting it caused Forgejo to reset use_custom_avatar on each call.
|
|
||||||
let body = format!(r#"{{"email":"{email}","login_name":"{name}","source_id":0}}"#);
|
|
||||||
let url = format!("{FORGE_HTTP}/api/v1/admin/users/{name}");
|
let url = format!("{FORGE_HTTP}/api/v1/admin/users/{name}");
|
||||||
match forge_http(reqwest::Method::PATCH, &url, &token, &body).await {
|
match forge_http(reqwest::Method::PATCH, &url, &token, &body).await {
|
||||||
Ok(status) if status.is_success() => {
|
Ok(status) if status.is_success() => {
|
||||||
std::fs::write(&marker, "").ok();
|
tracing::debug!(%name, %email, "forge: user email aligned");
|
||||||
tracing::info!(%name, %email, "forge: user email aligned");
|
|
||||||
}
|
}
|
||||||
Ok(status) if status == reqwest::StatusCode::FORBIDDEN => {
|
Ok(status) if status == reqwest::StatusCode::FORBIDDEN => {
|
||||||
// Core token missing admin scope — see
|
// Core token missing admin scope — see
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue