hive-c0re: stop reporting refused invites as success; re-register the config-PR hook when its secret changes
invite_user_id mapped every 403 M_FORBIDDEN to Ok(()). The membership pre-check already skips invited/joined users, so the 403s that reach the POST are mostly real refusals (banned target, sender without power), including `hivectl matrix invite`. A 403 is now success only when a membership re-read shows the user invited or joined; otherwise it is an error carrying the status and body. admin_room_send_and_poll read the send response's event_id with unwrap_or_default() and, when it was missing, walked every recent event unanchored, so an older bot reply (an earlier reset password) could be returned as this command's result. A send response without an event_id is now an error. run_destroy_bookkeeping discarded fail_pending_for_agent's error; it now warns like its neighbouring steps. ensure_config_pr_webhook returned as soon as a hook with the target URL existed, so a regenerated webhook-secret never reached Forgejo and every config-PR delivery failed HMAC until the 5-minute poll caught up. Forgejo's edit-hook API ignores `secret` and never returns it, so the SHA-256 of the secret last registered is recorded at forge/config-pr-webhook-secret-sha256; when it doesn't match, the same-URL hook is deleted and recreated. The paths.rs doc claiming re-registration on change now describes this. Refs #4723
This commit is contained in:
parent
0f58cdbde2
commit
bfd8189900
5 changed files with 291 additions and 61 deletions
|
|
@ -61,8 +61,9 @@ pub fn db_dir() -> PathBuf {
|
|||
|
||||
/// `webhook-secret` — hex-encoded 32-byte HMAC secret shared between
|
||||
/// hive-c0re's webhook handlers and the Forgejo webhook registrations.
|
||||
/// Generated on first startup and persisted; Forgejo is re-registered
|
||||
/// whenever the secret changes.
|
||||
/// Generated on first startup and persisted. The config-PR hook is replaced
|
||||
/// at the next boot-time registration when this no longer matches
|
||||
/// [`forge_config_pr_webhook_fingerprint`].
|
||||
#[must_use]
|
||||
pub fn webhook_secret_file() -> PathBuf {
|
||||
state_root().join("webhook-secret")
|
||||
|
|
@ -74,6 +75,15 @@ pub fn forge_dir() -> PathBuf {
|
|||
state_root().join("forge")
|
||||
}
|
||||
|
||||
/// `forge/config-pr-webhook-secret-sha256` — SHA-256 of the webhook secret
|
||||
/// the config-PR hook was last registered with. Forgejo never returns a
|
||||
/// hook's secret, so this is the only record of which one it signs with;
|
||||
/// delete to force the hook to be replaced.
|
||||
#[must_use]
|
||||
pub fn forge_config_pr_webhook_fingerprint() -> PathBuf {
|
||||
forge_dir().join("config-pr-webhook-secret-sha256")
|
||||
}
|
||||
|
||||
/// `forge/core-avatar-set` — marker: core account avatar uploaded.
|
||||
#[must_use]
|
||||
pub fn forge_core_avatar_marker() -> PathBuf {
|
||||
|
|
|
|||
Loading…
Reference in a new issue