Skip to content

Commit

Permalink
Merge pull request #4 from asonix/add-better-docs
Browse files Browse the repository at this point in the history
Add better docs
  • Loading branch information
asonix authored Jan 15, 2018
2 parents 2018555 + 2f3705d commit 958244e
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 38 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ version = "0.1.2"
license = "GPL-3.0"
authors = ["Riley Trautman <[email protected]>"]
repository = "https://github.com/asonix/http-signatures"
documentation = "https://asonix.github.io/http-signatures/http_signatures/index.html"
readme = "README.md"
keywords = ["web", "http", "signatures"]

Expand Down
2 changes: 1 addition & 1 deletion examples/hyper_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use http_signatures::{WithHttpSignature, SignatureAlgorithm, ShaSize};

fn main() {
let key_id = "some-username-or-something";
let private_key = File::open("test/assets/private.der").unwrap();
let private_key = File::open("tests/assets/private.der").unwrap();

let mut core = Core::new().unwrap();
let client = Client::new(&core.handle());
Expand Down
2 changes: 1 addition & 1 deletion examples/hyper_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
let server = Http::new()
.bind(&addr, || {
Ok(HelloWorld::new("test/assets/public.der").unwrap())
Ok(HelloWorld::new("tests/assets/public.der").unwrap())
})
.unwrap();
server.run().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion examples/reqwest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use http_signatures::{WithHttpSignature, SignatureAlgorithm, ShaSize};

fn main() {
let key_id = "some-username-or-something".into();
let private_key = File::open("test/assets/private.der").unwrap();
let private_key = File::open("tests/assets/private.der").unwrap();

let client = Client::new();
let mut req = client.get("http://localhost:8000").build().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion examples/rocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn index(_verified: Verified) -> &'static str {
}

fn main() {
let key_getter = MyKeyGetter::new("test/assets/public.der").unwrap();
let key_getter = MyKeyGetter::new("tests/assets/public.der").unwrap();

rocket::ignite()
.mount("/", routes![index])
Expand Down
124 changes: 118 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

//! This module defines the Error types for http_signatures.

use std::error::Error as StdError;
use std::fmt;
use std::io::Error as IoError;
use std::str::Utf8Error;

Expand All @@ -27,8 +29,6 @@ pub enum Error {
Verification(VerificationError),
/// Problems creating a signature
Creation(CreationError),
/// Unknown error occurred
Unknown,
}

impl From<IoError> for Error {
Expand All @@ -55,6 +55,34 @@ impl From<CreationError> for Error {
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::IO(ref ie) => write!(f, "{}", ie),
Error::Verification(ref ve) => write!(f, "{}", ve),
Error::Creation(ref ce) => write!(f, "{}", ce),
}
}
}

impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::IO(ref ie) => ie.description(),
Error::Verification(ref ve) => ve.description(),
Error::Creation(ref ce) => ce.description(),
}
}

fn cause(&self) -> Option<&StdError> {
match *self {
Error::IO(ref ie) => Some(ie),
Error::Verification(ref ve) => Some(ve),
Error::Creation(ref ce) => Some(ce),
}
}
}

/// When creating a signature doesn't work
#[derive(Debug)]
pub enum CreationError {
Expand All @@ -74,8 +102,35 @@ impl From<IoError> for CreationError {
}
}

impl fmt::Display for CreationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
CreationError::IO(ref io) => write!(f, "{}, {}", self.description(), io),
_ => write!(f, "{}", self.description()),
}
}
}

impl StdError for CreationError {
fn description(&self) -> &str {
match *self {
CreationError::IO(_) => "Signature creation: Error reading keys",
CreationError::NoHeaders => "Signature creation: Must provide at least one header",
CreationError::SigningError => "Signature creation: Error signing",
CreationError::BadPrivateKey => "Signature creation: Provided private key is invalid",
}
}

fn cause(&self) -> Option<&StdError> {
match *self {
CreationError::IO(ref ie) => Some(ie),
_ => None,
}
}
}

/// When decoding a signature doesn't work
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum DecodeError {
/// A required key is missing
MissingKey(&'static str),
Expand All @@ -85,8 +140,34 @@ pub enum DecodeError {
NotBase64,
}

impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
DecodeError::MissingKey(ref mk) => write!(f, "Missing key: {}", mk),
DecodeError::InvalidAlgorithm(ref ia) => write!(f, "Invalid Algorithm: {}", ia),
_ => write!(f, "{}", self.description()),
}
}
}

impl StdError for DecodeError {
fn description(&self) -> &str {
match *self {
DecodeError::MissingKey(_) => "Decoding: Missing key",
DecodeError::InvalidAlgorithm(_) => "Decoding: Provided algorithm is not supported",
DecodeError::NotBase64 => "Decoding: Provided signature is not base64 encoded",
}
}

fn cause(&self) -> Option<&StdError> {
match *self {
_ => None,
}
}
}

/// When a request cannot be verified
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum VerificationError {
/// Issues decoding a signature
Decode(DecodeError),
Expand All @@ -102,8 +183,6 @@ pub enum VerificationError {
BadSignature,
/// When the Authorization header is missing
HeaderNotPresent,
/// When we're not sure what went wrong
Unknown,
}

impl From<Utf8Error> for VerificationError {
Expand All @@ -117,3 +196,36 @@ impl From<DecodeError> for VerificationError {
VerificationError::Decode(d)
}
}

impl fmt::Display for VerificationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
VerificationError::Decode(ref de) => write!(f, "Verification: {}", de),
VerificationError::MissingHeaders(ref mh) => write!(f, "{}, {}", self.description(), mh),
VerificationError::Utf8(ref ue) => write!(f, "Verification: reading headers: {}", ue),
_ => write!(f, "{}", self.description()),
}
}
}

impl StdError for VerificationError {
fn description(&self) -> &str {
match *self {
VerificationError::Decode(ref de) => de.description(),
VerificationError::MissingHeaders(_) => "Verification: Headers provided in headers field are not present in the request",
VerificationError::Utf8(ref ue) => ue.description(),
VerificationError::GetKey => "Verification: Error getting key",
VerificationError::ReadKey => "Verification: Error reading key",
VerificationError::BadSignature => "Verification: Bad signature",
VerificationError::HeaderNotPresent => "Verification: Header missing",
}
}

fn cause(&self) -> Option<&StdError> {
match *self {
VerificationError::Decode(ref de) => Some(de),
VerificationError::Utf8(ref ue) => Some(ue),
_ => None,
}
}
}
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ extern crate base64;
use std::convert::TryFrom;

#[cfg(feature = "use_hyper")]
mod use_hyper_client;
pub mod use_hyper_client;
#[cfg(feature = "use_hyper")]
mod use_hyper_server;
pub mod use_hyper_server;
#[cfg(feature = "use_reqwest")]
mod use_reqwest;
pub mod use_reqwest;
#[cfg(feature = "use_rocket")]
mod use_rocket;
pub mod use_rocket;

mod create;
mod verify;
Expand Down
73 changes: 73 additions & 0 deletions src/use_hyper_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,79 @@
// You should have received a copy of the GNU General Public License
// along with HTTP Signatures If not, see <http://www.gnu.org/licenses/>.

//! Available with the `use_hyper` feature. This modulde defines the `AsHttpSignature` and
//! `WithHttpSignature` traits for `hyper::Request`.
//!
//! This is useful for interacting with HTTP Signatures from Hyper-based applications, since it can
//! automatically generate signatures and add them to requests.
//!
//! # Example generating a signature
//! This example shows getting an `HttpSignature` type from a `hyper::Request`. Typically you
//! wouldn't want to do this directly, you'd use `with_authorization_header` or
//! `with_signature_header` directly, but in the event you want the intermediate state, this is
//! available.
//!
//! ```rust
//! # #![feature(try_from)]
//! # extern crate hyper;
//! # extern crate http_signatures;
//! #
//! # use std::convert::TryInto;
//! # use std::error::Error;
//! # use std::fs::File;
//! #
//! # use http_signatures::{AsHttpSignature, ShaSize, SignatureAlgorithm};
//! # use hyper::{Method, Request};
//! #
//! # fn run() -> Result<(), Box<Error>> {
//! let key = File::open("tests/assets/private.der")?;
//! let uri = "https://example.com".parse()?;
//! let alg = SignatureAlgorithm::RSA(ShaSize::TwoFiftySix);
//!
//! let req: Request = Request::new(Method::Post, uri);
//!
//! let http_sig = req.as_http_signature("rsa-key-1".into(), key, alg)?;
//! # Ok(())
//! # }
//! # fn main() {
//! # run().unwrap();
//! # }
//! ```
//!
//! # Example adding a signature to a Request type
//!
//! This example adds the HTTP Signature to the request directly as an Authorization header.
//! `with_signature_header` can be used to add the signature as a Signature header instead.
//!
//! ```rust
//! # extern crate hyper;
//! # extern crate http_signatures;
//! #
//! # use std::error::Error;
//! # use std::fs::File;
//! #
//! # use http_signatures::{WithHttpSignature, ShaSize, SignatureAlgorithm};
//! # use hyper::{Method, Request};
//! #
//! # fn run() -> Result<(), Box<Error>> {
//! let key = File::open("tests/assets/private.der")?;
//! let uri = "https://example.com".parse()?;
//! let alg = SignatureAlgorithm::RSA(ShaSize::TwoFiftySix);
//!
//! let mut req: Request = Request::new(Method::Post, uri);
//!
//! req.with_authorization_header("rsa-key-1".into(), key, alg)?;
//! # Ok(())
//! # }
//! # fn main() {
//! # run().unwrap();
//! # }
//! ```
//!
//! See
//! [this example](https://github.com/asonix/http-signatures/blob/master/examples/hyper_client.rs)
//! for more information.

use std::io::Read;
use std::collections::BTreeMap;

Expand Down
15 changes: 9 additions & 6 deletions src/use_hyper_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
// You should have received a copy of the GNU General Public License
// along with HTTP Signatures If not, see <http://www.gnu.org/licenses/>.

//! Available with the `use_hyper` feature. This module defines `VerifyHeader` for
//! `hyper::server::Request`.
//!
//! This allows easy verification of incomming requests in Hyper.
//!
//! See
//! [this example](https://github.com/asonix/http-signatures/blob/master/examples/hyper_server.rs)
//! for usage information.

use std::str::from_utf8;

use hyper::header::Authorization;
Expand All @@ -21,12 +30,6 @@ use hyper::server::Request;
use verify::{SignedHeader, VerifyHeader, GetKey};
use error::VerificationError;

/// Implements `VerifyHeader` for `hyper::server::Request`.
///
/// This allows easy verification of incomming requests in Hyper.
///
/// See [https://github.com/asonix/http-signatures/blob/master/examples/hyper_server.rs](this
/// example) for usage information.
impl VerifyHeader for Request {
fn verify_signature_header<G: GetKey>(&self, key_getter: G) -> Result<(), VerificationError> {
let auth_header = self.headers()
Expand Down
Loading

0 comments on commit 958244e

Please sign in to comment.