~vpzom/hancock

b889dc1b310f3078297a51af2f7266b718c411ab — Colin Reeder 4 years ago fc8aa0a
Add some documentation
1 files changed, 41 insertions(+), 0 deletions(-)

M src/lib.rs
M src/lib.rs => src/lib.rs +41 -0
@@ 1,29 1,53 @@
//! HTTP Signature handling utility.
//!
//! More details in the `Signature` struct

#![warn(missing_docs)]

/// Errors that may be produced when parsing a signature header
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
    /// A parameter pair did not contain `=`
    #[error("Parameter pair did not contain =")]
    MissingEquals,

    /// Didn't find a signature in the header
    #[error("No signature found in parameters")]
    MissingSignature,

    /// A parameter contained invalid characters
    #[error("Parameter contained invalid characters")]
    InvalidCharacters,

    /// Failed to parse a number
    #[error("Failed to parse number")]
    Number(std::num::ParseIntError),

    /// Signature field was not valid Base64
    #[error("Failed to parse signature bytes")]
    Base64(base64::DecodeError),
}

/// Errors that may be produced when creating a signature
#[derive(Debug, thiserror::Error)]
pub enum SignError<T: std::fmt::Debug> {
    /// An IO error occurred.
    #[error("IO error occurred")]
    IO(#[from] std::io::Error),

    /// An error was returned from the provided `sign` function.
    #[error("Failed in user sign call")]
    User(T),
}

/// Errors that may be produced when verifying a signature
#[derive(Debug, thiserror::Error)]
pub enum VerifyError<T: std::fmt::Debug> {
    /// An IO error occurred.
    #[error("IO error occurred")]
    IO(#[from] std::io::Error),

    /// An error was returned from the provided `verify` function.
    #[error("Failed in user verify call")]
    User(T),
}


@@ 78,6 102,7 @@ fn parse_maybe_quoted<'a>(src: &'a str) -> &'a str {
    }
}

/// A parsed or generated Signature.
pub struct Signature<'a> {
    algorithm: Option<http::header::HeaderName>,
    created: Option<u64>,


@@ 88,6 113,12 @@ pub struct Signature<'a> {
}

impl<'a> Signature<'a> {
    /// Construct a signature.
    ///
    /// All headers in `headers` will be included, as well as `(request-target)`, `(created)`, and
    /// `(expires)` (based on `lifetime_secs` parameter)
    ///
    /// The passed `sign` will be called with the body to sign.
    pub fn create<E: std::fmt::Debug>(
        key_id: &'a str,
        request_method: &http::method::Method,


@@ 151,6 182,10 @@ impl<'a> Signature<'a> {
        })
    }

    /// Create an old-style signature (no (created) and (expires))
    ///
    /// # Panics
    /// Panics if `headers` doesn't contain a Date header
    pub fn create_legacy<E: std::fmt::Debug>(
        key_id: &'a str,
        request_method: &http::method::Method,


@@ 204,6 239,7 @@ impl<'a> Signature<'a> {
        })
    }

    /// Parse a Signature header
    pub fn parse(value: &'a http::header::HeaderValue) -> Result<Self, ParseError> {
        let mut algorithm = None;
        let mut created = None;


@@ 260,6 296,7 @@ impl<'a> Signature<'a> {
        })
    }

    /// Create a Signature header value for the signature.
    pub fn to_header(&self) -> http::header::HeaderValue {
        use std::fmt::Write;
        let mut params = String::new();


@@ 297,6 334,10 @@ impl<'a> Signature<'a> {
        http::header::HeaderValue::from_bytes(params.as_bytes()).unwrap()
    }

    /// Verify the signature for a given request target and HeaderMap.
    ///
    /// The passed `verify` function will be called with (body, signature) where body is the body
    /// that should match the signature.
    pub fn verify<E: std::fmt::Debug>(
        &self,
        request_method: &http::method::Method,