diff options
author | Alex Auvolat <alex@adnab.me> | 2020-11-08 15:04:30 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-11-08 15:05:28 +0100 |
commit | a50fa70d45f8b5af68d23d60c3bac2af4ecceb58 (patch) | |
tree | d3014cc2739c5a1bce62ff35efc8417b79ff46ef /src/api/signature.rs | |
parent | 54166d2a09f488bff080469160d4df6a78db1a3f (diff) | |
download | garage-a50fa70d45f8b5af68d23d60c3bac2af4ecceb58.tar.gz garage-a50fa70d45f8b5af68d23d60c3bac2af4ecceb58.zip |
Refactor error management in API parterror-refactoring
Diffstat (limited to 'src/api/signature.rs')
-rw-r--r-- | src/api/signature.rs | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/src/api/signature.rs b/src/api/signature.rs index 6e23afda..402b1881 100644 --- a/src/api/signature.rs +++ b/src/api/signature.rs @@ -7,12 +7,12 @@ use sha2::{Digest, Sha256}; use garage_table::*; use garage_util::data::Hash; -use garage_util::error::Error; use garage_model::garage::Garage; use garage_model::key_table::*; use crate::encoding::uri_encode; +use crate::error::*; const SHORT_DATE: &str = "%Y%m%d"; const LONG_DATETIME: &str = "%Y%m%dT%H%M%SZ"; @@ -42,9 +42,9 @@ pub async fn check_signature( let date = headers .get("x-amz-date") - .ok_or(Error::BadRequest("Missing X-Amz-Date field".into()))?; + .ok_or_bad_request("Missing X-Amz-Date field")?; let date: NaiveDateTime = NaiveDateTime::parse_from_str(date, LONG_DATETIME) - .map_err(|e| Error::BadRequest(format!("Invalid date: {}", e)))? + .ok_or_bad_request("Invalid date")? .into(); let date: DateTime<Utc> = DateTime::from_utc(date, Utc); @@ -90,7 +90,7 @@ pub async fn check_signature( &garage.config.s3_api.s3_region, "s3", ) - .map_err(|e| Error::Message(format!("Unable to build signing HMAC: {}", e)))?; + .ok_or_internal_error("Unable to build signing HMAC")?; hmac.input(string_to_sign.as_bytes()); let signature = hex::encode(hmac.result().code()); @@ -104,9 +104,8 @@ pub async fn check_signature( let content_sha256 = if authorization.content_sha256 == "UNSIGNED-PAYLOAD" { None } else { - let bytes = hex::decode(authorization.content_sha256).or(Err(Error::BadRequest( - format!("Invalid content sha256 hash"), - )))?; + let bytes = hex::decode(authorization.content_sha256) + .ok_or_bad_request("Invalid content sha256 hash")?; let mut hash = [0u8; 32]; if bytes.len() != 32 { return Err(Error::BadRequest(format!("Invalid content sha256 hash"))); @@ -132,7 +131,7 @@ fn parse_authorization( ) -> Result<Authorization, Error> { let first_space = authorization .find(' ') - .ok_or(Error::BadRequest("Authorization field too short".into()))?; + .ok_or_bad_request("Authorization field to short")?; let (auth_kind, rest) = authorization.split_at(first_space); if auth_kind != "AWS4-HMAC-SHA256" { @@ -142,41 +141,32 @@ fn parse_authorization( let mut auth_params = HashMap::new(); for auth_part in rest.split(',') { let auth_part = auth_part.trim(); - let eq = auth_part.find('=').ok_or(Error::BadRequest(format!( - "Missing =value in authorization field {}", - auth_part - )))?; + let eq = auth_part + .find('=') + .ok_or_bad_request("Field without value in authorization header")?; let (key, value) = auth_part.split_at(eq); auth_params.insert(key.to_string(), value.trim_start_matches('=').to_string()); } let cred = auth_params .get("Credential") - .ok_or(Error::BadRequest(format!( - "Could not find Credential in Authorization field" - )))?; + .ok_or_bad_request("Could not find Credential in Authorization field")?; let (key_id, scope) = parse_credential(cred)?; let content_sha256 = headers .get("x-amz-content-sha256") - .ok_or(Error::BadRequest( - "Missing X-Amz-Content-Sha256 field".into(), - ))?; + .ok_or_bad_request("Missing X-Amz-Content-Sha256 field")?; let auth = Authorization { key_id, scope, signed_headers: auth_params .get("SignedHeaders") - .ok_or(Error::BadRequest(format!( - "Could not find SignedHeaders in Authorization field" - )))? + .ok_or_bad_request("Could not find SignedHeaders in Authorization field")? .to_string(), signature: auth_params .get("Signature") - .ok_or(Error::BadRequest(format!( - "Could not find Signature in Authorization field" - )))? + .ok_or_bad_request("Could not find Signature in Authorization field")? .to_string(), content_sha256: content_sha256.to_string(), }; @@ -186,9 +176,7 @@ fn parse_authorization( fn parse_query_authorization(headers: &HashMap<String, String>) -> Result<Authorization, Error> { let algo = headers .get("x-amz-algorithm") - .ok_or(Error::BadRequest(format!( - "X-Amz-Algorithm not found in query parameters" - )))?; + .ok_or_bad_request("X-Amz-Algorithm not found in query parameters")?; if algo != "AWS4-HMAC-SHA256" { return Err(Error::BadRequest(format!( "Unsupported authorization method" @@ -197,20 +185,14 @@ fn parse_query_authorization(headers: &HashMap<String, String>) -> Result<Author let cred = headers .get("x-amz-credential") - .ok_or(Error::BadRequest(format!( - "X-Amz-Credential not found in query parameters" - )))?; + .ok_or_bad_request("X-Amz-Credential not found in query parameters")?; let (key_id, scope) = parse_credential(cred)?; let signed_headers = headers .get("x-amz-signedheaders") - .ok_or(Error::BadRequest(format!( - "X-Amz-SignedHeaders not found in query parameters" - )))?; + .ok_or_bad_request("X-Amz-SignedHeaders not found in query parameters")?; let signature = headers .get("x-amz-signature") - .ok_or(Error::BadRequest(format!( - "X-Amz-Signature not found in query parameters" - )))?; + .ok_or_bad_request("X-Amz-Signature not found in query parameters")?; let content_sha256 = headers .get("x-amz-content-sha256") .map(|x| x.as_str()) @@ -226,9 +208,9 @@ fn parse_query_authorization(headers: &HashMap<String, String>) -> Result<Author } fn parse_credential(cred: &str) -> Result<(String, String), Error> { - let first_slash = cred.find('/').ok_or(Error::BadRequest(format!( - "Credentials does not contain / in authorization field" - )))?; + let first_slash = cred + .find('/') + .ok_or_bad_request("Credentials does not contain / in authorization field")?; let (key_id, scope) = cred.split_at(first_slash); Ok(( key_id.to_string(), |