Skip to content

Commit

Permalink
feat: Implement sign method
Browse files Browse the repository at this point in the history
  • Loading branch information
carols10cents committed Sep 28, 2023
1 parent 0aaa2fd commit af87fd3
Showing 1 changed file with 67 additions and 1 deletion.
68 changes: 67 additions & 1 deletion object_store/src/aws/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,64 @@ impl<'a> AwsAuthorizer<'a> {
request.headers_mut().insert(AUTH_HEADER, authorization_val);
}

/// Authorize a request via `method` to `url` by attaching the relevant [AWS SigV4] query parameters.
///
/// [AWS SigV4]: https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html
pub fn sign(&self, method: Method, url: &mut Url) {
let date = self.date.unwrap_or_else(Utc::now);

let digest = UNSIGNED_PAYLOAD;

let canonical_uri = match self.service {
"s3" => url.path().to_string(),
_ => utf8_percent_encode(url.path(), &STRICT_PATH_ENCODE_SET)
.to_string(),
};

let mut headers = HeaderMap::new();

if let Some(ref token) = self.credential.token {
let token_val = HeaderValue::from_str(token).unwrap();
headers.insert(TOKEN_HEADER, token_val);
}
let host = &url[url::Position::BeforeHost..url::Position::AfterPort];
let host_val = HeaderValue::from_str(host).unwrap();
headers.insert("host", host_val);

let date_str = date.format("%Y%m%dT%H%M%SZ").to_string();
let date_val = HeaderValue::from_str(&date_str).unwrap();
headers.insert(DATE_HEADER, date_val);

let header_digest = HeaderValue::from_str(digest).unwrap();
headers.insert(HASH_HEADER, header_digest);

let (signed_headers, canonical_headers) = canonicalize_headers(&headers);
let canonical_query = canonicalize_query(url);

let scope = self.scope(date);

let string_to_sign = self.string_to_sign(
date,
&scope,
&method,
&canonical_uri,
&canonical_query,
&canonical_headers,
&signed_headers,
digest,
);

let signature = self.credential
.sign(&string_to_sign, date, self.region, self.service);

url.query_pairs_mut()
.append_pair("X-Amz-Algorithm", ALGORITHM)
.append_pair("X-Amz-Credential", &format!("{}/{}", self.credential.key_id, scope))
.append_pair("X-Amz-Date", &date_str)
.append_pair("X-Amz-SignedHeaders", "host;x-amz-date")
.append_pair("X-Amz-Signature", &signature);
}

fn string_to_sign(
&self,
date: DateTime<Utc>,
Expand Down Expand Up @@ -697,7 +755,15 @@ mod tests {
};

authorizer.authorize(&mut request, None);
assert_eq!(request.headers().get(AUTH_HEADER).unwrap(), "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=653c3d8ea261fd826207df58bc2bb69fbb5003e9eb3c0ef06e4a51f2a81d8699")
assert_eq!(request.headers().get(AUTH_HEADER).unwrap(), "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=653c3d8ea261fd826207df58bc2bb69fbb5003e9eb3c0ef06e4a51f2a81d8699");

let mut url = Url::parse("https://ec2.amazon.com/").unwrap();
authorizer.sign(Method::GET, &mut url);
assert_eq!(url.query().unwrap(), "X-Amz-Algorithm=AWS4-HMAC-SHA256&\
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20220806%2Fus-east-1%2Fec2%2Faws4_request&\
X-Amz-Date=20220806T180134Z&\
X-Amz-SignedHeaders=host%3Bx-amz-date&\
X-Amz-Signature=653c3d8ea261fd826207df58bc2bb69fbb5003e9eb3c0ef06e4a51f2a81d8699");
}

#[test]
Expand Down

0 comments on commit af87fd3

Please sign in to comment.