#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
extern crate http_signatures;
use std::io::{Cursor, Read};
use rocket::State;
use rocket::Outcome::{Success, Failure};
use rocket::request::{Request, FromRequest, Outcome};
use rocket::http::Status;
use http_signatures::{GetKey, VerifyHeader};
#[derive(Debug)]
enum Error {
FileError,
}
#[derive(Clone)]
struct MyKeyGetter {
key: Vec<u8>,
}
impl MyKeyGetter {
fn new(filename: &str) -> Result<Self, Error> {
let mut key = Vec::new();
std::fs::File::open(filename)
.map_err(|_| Error::FileError)?
.read_to_end(&mut key)
.map_err(|_| Error::FileError)?;
Ok(MyKeyGetter { key })
}
}
impl GetKey for MyKeyGetter {
type Key = Cursor<Vec<u8>>;
type Error = Error;
fn get_key(self, _key_id: &str) -> Result<Self::Key, Self::Error> {
Ok(Cursor::new(self.key.clone()))
}
}
struct Verified;
impl<'a, 'r> FromRequest<'a, 'r> for Verified {
type Error = ();
fn from_request(request: &'a Request<'r>) -> Outcome<Verified, ()> {
let res = request
.guard::<State<MyKeyGetter>>()
.succeeded()
.ok_or(())
.and_then(|key_getter| {
request
.verify_authorization_header(key_getter.clone())
.map_err(|e| println!("Error: {:?}", e))?;
Ok(Verified)
});
match res {
Ok(verified) => Success(verified),
Err(fail) => Failure((Status::Forbidden, fail)),
}
}
}
#[get("/")]
fn index(_verified: Verified) -> &'static str {
"Successfully verified request"
}
fn main() {
let key_getter = MyKeyGetter::new("test/assets/public.der").unwrap();
rocket::ignite()
.mount("/", routes![index])
.manage(key_getter)
.launch();
}