openapi_rs/common/
signer.rs

1use crate::common::crypt::md5::md5;
2use crate::common::crypt::sha1::sha1;
3use crate::common::define::BaseRequest;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fmt::Write;
7use std::str::from_utf8;
8
9#[derive(Default, Debug, Serialize, Deserialize)]
10pub struct Signer {
11    pub app_key: String,
12    pub app_secret: String,
13}
14
15impl Signer {
16    pub fn new(app_key: &str, app_secret: &str) -> Self {
17        Self {
18            app_key: app_key.to_string(),
19            app_secret: app_secret.to_string(),
20        }
21    }
22
23    pub fn sign_request(
24        &self,
25        base_request: &BaseRequest,
26        queries: &HashMap<String, String>,
27    ) -> anyhow::Result<String> {
28        let mut queries = queries.clone();
29        if !base_request.body.is_empty() {
30            if let Some(content_type) = &base_request.content_type {
31                if content_type.as_str().starts_with("application/json") {
32                    queries.insert("_body".to_string(), sha1(from_utf8(&base_request.body)?));
33                }
34            }
35        }
36        self.sign(&queries)
37    }
38
39    pub fn sign(&self, queries: &HashMap<String, String>) -> anyhow::Result<String> {
40        let mut keys: Vec<String> = queries
41            .keys()
42            .filter(|k| !k.as_str().eq("Signature"))
43            .map(|k| k.to_string())
44            .collect();
45        keys.sort();
46
47        let mut buffer = String::new();
48        for key in keys {
49            if let Some(val) = queries.get(&key) {
50                write!(buffer, "{}={}", key, val)?;
51            }
52        }
53        buffer.push_str(&self.app_secret);
54
55        Ok(md5(&buffer))
56    }
57}