mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-05 08:10:39 +00:00
Simplify webhook module: deduplicate PEM decoding, extract delivery_id, remove redundant state
- Reuse jwt_auth::decode_pem_env in read_github_private_key instead of duplicating base64/PEM logic - Extract delivery_id once at top of webhook_handler instead of 3 separate times - Remove redundant funnel_port field from WebhookManager (derive from listener.port()) - Gate parse_event_metadata behind debug log level to avoid full JSON parse on every webhook Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d838fda004
commit
2355cd573d
3 changed files with 28 additions and 35 deletions
|
|
@ -43,26 +43,23 @@ async fn webhook_handler(
|
|||
headers: HeaderMap,
|
||||
body: Bytes,
|
||||
) -> StatusCode {
|
||||
let delivery_id = headers
|
||||
.get("x-github-delivery")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("unknown");
|
||||
|
||||
let signature = match headers
|
||||
.get("x-hub-signature-256")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
{
|
||||
Some(s) => s,
|
||||
None => {
|
||||
let delivery_id = headers
|
||||
.get("x-github-delivery")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("unknown");
|
||||
warn!(delivery = %delivery_id, "Webhook signature verification failed");
|
||||
return StatusCode::UNAUTHORIZED;
|
||||
}
|
||||
};
|
||||
|
||||
if !verify_signature(&state.secret, &body, signature) {
|
||||
let delivery_id = headers
|
||||
.get("x-github-delivery")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("unknown");
|
||||
warn!(delivery = %delivery_id, "Webhook signature verification failed");
|
||||
return StatusCode::UNAUTHORIZED;
|
||||
}
|
||||
|
|
@ -71,20 +68,23 @@ async fn webhook_handler(
|
|||
.get("x-github-event")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("unknown");
|
||||
let delivery_id = headers
|
||||
.get("x-github-delivery")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("unknown");
|
||||
|
||||
let (repo, action) = parse_event_metadata(&body);
|
||||
|
||||
debug!(
|
||||
event = %event_type,
|
||||
delivery = %delivery_id,
|
||||
repo = %repo,
|
||||
action = %action,
|
||||
"Webhook received"
|
||||
);
|
||||
if tracing::enabled!(tracing::Level::DEBUG) {
|
||||
let (repo, action) = parse_event_metadata(&body);
|
||||
debug!(
|
||||
event = %event_type,
|
||||
delivery = %delivery_id,
|
||||
repo = %repo,
|
||||
action = %action,
|
||||
"Webhook received"
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
event = %event_type,
|
||||
delivery = %delivery_id,
|
||||
"Webhook received"
|
||||
);
|
||||
}
|
||||
|
||||
StatusCode::OK
|
||||
}
|
||||
|
|
@ -151,7 +151,6 @@ pub async fn spawn_webhook_listener(secret: Vec<u8>) -> anyhow::Result<WebhookLi
|
|||
/// Manage the full webhook lifecycle: listener + tailscale funnel + GitHub API.
|
||||
pub struct WebhookManager {
|
||||
listener: WebhookListener,
|
||||
funnel_port: u16,
|
||||
}
|
||||
|
||||
impl WebhookManager {
|
||||
|
|
@ -188,15 +187,12 @@ impl WebhookManager {
|
|||
|
||||
info!(url = %webhook_url, "GitHub App webhook URL updated");
|
||||
|
||||
Ok(Self {
|
||||
listener,
|
||||
funnel_port: port,
|
||||
})
|
||||
Ok(Self { listener })
|
||||
}
|
||||
|
||||
/// Shut down: disable funnel, stop listener.
|
||||
pub async fn shutdown(self) {
|
||||
disable_tailscale_funnel(self.funnel_port).await;
|
||||
disable_tailscale_funnel(self.listener.port()).await;
|
||||
self.listener.shutdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ pub enum AuthMode {
|
|||
pub struct PeerCertificates(pub Option<Vec<CertificateDer<'static>>>);
|
||||
|
||||
/// Decode a PEM env var that may be raw PEM or base64-encoded PEM.
|
||||
fn decode_pem_env(name: &str, value: &str) -> String {
|
||||
pub fn decode_pem_env(name: &str, value: &str) -> String {
|
||||
if value.starts_with("-----") {
|
||||
return value.to_string();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -307,13 +307,10 @@ fn resolve_model_provider(
|
|||
/// Read the GitHub App private key from the environment, decoding base64 if needed.
|
||||
fn read_github_private_key() -> Option<String> {
|
||||
let raw = std::env::var("GITHUB_APP_PRIVATE_KEY").ok()?;
|
||||
if raw.starts_with("-----") {
|
||||
Some(raw)
|
||||
} else {
|
||||
let pem_bytes =
|
||||
base64::Engine::decode(&base64::engine::general_purpose::STANDARD, &raw).ok()?;
|
||||
String::from_utf8(pem_bytes).ok()
|
||||
}
|
||||
Some(crate::jwt_auth::decode_pem_env(
|
||||
"GITHUB_APP_PRIVATE_KEY",
|
||||
&raw,
|
||||
))
|
||||
}
|
||||
|
||||
/// Derive client certificate verification mode from the resolved auth strategies.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue