1use crypto::hmac::Hmac;
4use crypto::mac::{Mac, MacResult};
5use crypto::sha2::Sha256;
6
7pub use hex::FromHexError;
8
9pub fn verify(
27 secret: &str,
28 body: &str,
29 timestamp: i64,
30 expected_hex: &str,
31) -> Result<bool, hex::FromHexError> {
32 let sig_basestring = format!("v0:{}:{}", timestamp, body);
33
34 let mut hasher = Hmac::new(Sha256::new(), secret.as_bytes());
35
36 hasher.input(sig_basestring.as_bytes());
37
38 let expected = hex::decode(expected_hex.replacen("v0=", "", 1).as_bytes())?;
39
40 Ok(hasher.result() == MacResult::new_from_owned(expected))
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_get_sig_basestring() {
49 let secret = "8f742231b10e8888abcd99yyyzzz85a5";
50 let body = "token=xyzz0WbapA4vBCDEFasx0q6G&team_id=T1DC2JH3J&team_domain=testteamnow&channel_id=G8PSS9T3V&channel_name=foobar&user_id=U2CERLKJA&user_name=roadrunner&command=%2Fwebhook-collect&text=&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT1DC2JH3J%2F397700885554%2F96rGlfmibIGlgcZRskXaIFfN&trigger_id=398738663015.47445629121.803a0bc887a14d10d2c447fce8b6703c";
51 let timestamp = 1531420618;
52 let expected = "v0=a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503";
53
54 let output = verify(secret, body, timestamp, expected);
55 assert_eq!(output.unwrap(), true);
56 }
57}