alibaba_cloud_sdk_rust/sdk/auth/singers/
rpc_signature_composer.rs1#![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", ®ionId);
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}