alibaba_cloud_sdk_rust/sdk/auth/singers/
rpc_signature_composer.rs

1#![allow(unused)]
2#![allow(non_upper_case_globals)]
3#![allow(non_snake_case)]
4#![allow(non_camel_case_types)]
5use super::Signer;
6use crate::error::AliyunResult;
7use crate::error::AliyunSDKError::AliyunSMSError;
8use crate::sdk::requests;
9use crate::sdk::requests::BaseRequestExt;
10use gostd::net::url;
11use gostd::net::url::Values;
12use gostd::strings;
13use gostd::time;
14use log::debug;
15use std::{
16    borrow::{Borrow, BorrowMut},
17    collections::HashMap,
18};
19pub fn signRpcRequest(
20    request: &mut requests::AcsRequest,
21    signer: Option<Box<dyn Signer>>,
22    regionId: &str,
23) -> AliyunResult<()> {
24    completeRpcSignParams(request, &signer, regionId)?;
25
26    if request.GetQueryParams().contains_key("Signature") {
27        request
28            .QueryParams_as_mut()
29            .remove("Signature")
30            .ok_or(AliyunSMSError("remove Signature failed ".to_string()));
31    }
32    let stringToSign = buildRpcStringToSign(request);
33    request.SetStringToSign(stringToSign.as_str());
34    let signature = signer
35        .ok_or(AliyunSMSError("signer is NONE".to_string()))?
36        .Sign(&stringToSign, "&");
37
38    request.addQueryParam("Signature", signature.as_str());
39    Ok(())
40}
41
42fn buildRpcStringToSign(request: &mut requests::RpcRequest) -> String {
43    let mut signParams = HashMap::new();
44
45    for (key, value) in request.GetQueryParams() {
46        signParams.insert(key.to_owned(), value.to_owned());
47    }
48
49    for (key, value) in request.GetFormParams() {
50        signParams.insert(key.to_owned(), value.to_owned());
51    }
52
53    let mut stringToSign = GetUrlFormedMap(&signParams);
54    stringToSign = strings::Replace(stringToSign, "+", "%20", -1);
55    stringToSign = strings::Replace(stringToSign, "*", "%2A", -1);
56    stringToSign = strings::Replace(stringToSign, "%7E", "~", -1);
57    stringToSign = url::QueryEscape(&stringToSign);
58    stringToSign = request.GetMethod().String().to_owned() + "&%2F&" + &stringToSign;
59    stringToSign
60}
61
62fn completeRpcSignParams(
63    request: &mut requests::AcsRequest,
64    signer: &Option<Box<dyn Signer>>,
65    regionId: &str,
66) -> AliyunResult<()> {
67    let signer = signer.as_ref().expect("signer is None");
68    let version = request.GetVersion().to_string();
69    let action = request.GetActionName().to_string();
70    let formart = request.GetAcceptFormat().to_string();
71    request.addQueryParam("Version", &version);
72    request.addQueryParam("Action", &action);
73    request.addQueryParam("Format", &formart);
74    request.addQueryParam("Timestamp", &GetTimeInFormatISO8601());
75    request.addQueryParam("SignatureMethod", &signer.GetName());
76    request.addQueryParam("SignatureType", &signer.GetType());
77    request.addQueryParam("SignatureVersion", &signer.GetVersion());
78    request.addQueryParam("SignatureNonce", &GetUUID());
79    request.addQueryParam("AccessKeyId", &signer.GetAccessKeyId()?);
80
81    if request.GetQueryParams().contains_key("RegionId") {
82        request.addQueryParam("RegionId", &regionId);
83    }
84
85    if let Some(param) = signer.GetExtraParam() {
86        param.iter().for_each(|(k, v)| request.addQueryParam(k, v));
87    }
88    request.addHeaderParam("Content-Type", requests::Form);
89
90    let formString = GetUrlFormedMap(request.GetFormParams());
91    request.SetContent(formString.as_bytes());
92    debug!("queryParams: {:?}", request.GetQueryParams());
93    Ok(())
94}
95
96pub fn GetUUID() -> String {
97    uuid::Uuid::new_v4().to_string()
98}
99pub fn GetTimeInFormatISO8601() -> String {
100    let gmt = time::FixedZone("GMT", 0);
101    time::Now().In(gmt).Format("2006-01-02T15:04:05Z")
102}
103
104pub fn GetUrlFormedMap(source: &HashMap<String, String>) -> String {
105    let mut map = HashMap::<String, Vec<String>>::new();
106    for (k, v) in source.iter() {
107        let mut vals: Vec<String> = vec![v.to_owned()];
108        map.insert(k.to_owned(), vals.to_owned());
109    }
110    let urlencoder = Values::new(map);
111    debug!("urlencoder: {}\n", urlencoder.Encode());
112    urlencoder.Encode()
113}