git-next-forge-github 0.14.1

GitHub support for git-next, the trunk-based development manager
Documentation
//

use std::string::ToString;

use git_next_core::{ForgeNotification, WebhookAuth};

use hmac::Mac;
type HmacSha256 = hmac::Hmac<sha2::Sha256>;

pub fn is_authorised(msg: &ForgeNotification, webhook_auth: &WebhookAuth) -> bool {
    msg.header("x-hub-signature-256")
        .map(|x| x.trim_matches('"').to_string())
        .and_then(|sha| sha.strip_prefix("sha256=").map(ToString::to_string))
        .and_then(|github_signature| hex::decode(github_signature).ok())
        .and_then(|gh_sig| {
            let payload = &msg.body().as_str();

            let mut hmac = HmacSha256::new_from_slice(webhook_auth.to_string().as_bytes()).ok()?;
            hmac::Mac::update(&mut hmac, payload.as_ref());
            Some(hmac::Mac::verify_slice(hmac, gh_sig.as_ref()).is_ok())
        })
        .unwrap_or_default()
}

#[cfg(test)]
pub fn sign_body(
    webhook_auth: &WebhookAuth,
    body: &git_next_core::webhook::forge_notification::Body,
) -> Option<String> {
    let payload = body.as_str();
    let mut hmac = HmacSha256::new_from_slice(webhook_auth.to_string().as_bytes()).ok()?;
    hmac::Mac::update(&mut hmac, payload.as_ref());
    let f = hmac::Mac::finalize(hmac);
    Some(hex::encode(f.into_bytes()))
}