http-signature-normalization/http-signature-normalization-actix/examples/server.rs
2019-09-21 11:29:41 -05:00

92 lines
2.1 KiB
Rust

use actix::System;
use actix_web::{web, App, HttpResponse, HttpServer, ResponseError};
use failure::Fail;
use http_signature_normalization_actix::{prelude::*, verify::Algorithm};
use sha2::{Digest, Sha256};
#[derive(Clone, Debug)]
struct MyVerify;
impl SignatureVerify for MyVerify {
type Error = MyError;
type Future = Result<bool, Self::Error>;
fn signature_verify(
&mut self,
algorithm: Option<Algorithm>,
key_id: &str,
signature: &str,
signing_string: &str,
) -> Self::Future {
match algorithm {
Some(Algorithm::Hs2019) => (),
_ => return Err(MyError::Algorithm),
};
if key_id != "my-key-id" {
return Err(MyError::Key);
}
let decoded = base64::decode(signature).map_err(|_| MyError::Decode)?;
Ok(decoded == signing_string.as_bytes())
}
}
fn index(_: (DigestVerified, SignatureVerified)) -> &'static str {
"Eyyyyup"
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let sys = System::new("server-example");
let config = Config::default();
HttpServer::new(move || {
App::new()
.wrap(VerifyDigest::new(Sha256::new()).optional())
.wrap(
VerifySignature::new(MyVerify, config.clone())
.authorization()
.optional(),
)
.route("/", web::post().to(index))
})
.bind("127.0.0.1:8010")?
.start();
sys.run()?;
Ok(())
}
#[derive(Debug, Fail)]
enum MyError {
#[fail(display = "Failed to verify, {}", _0)]
Verify(#[cause] PrepareVerifyError),
#[fail(display = "Unsupported algorithm")]
Algorithm,
#[fail(display = "Couldn't decode signature")]
Decode,
#[fail(display = "Invalid key")]
Key,
}
impl ResponseError for MyError {
fn error_response(&self) -> HttpResponse {
HttpResponse::BadRequest().finish()
}
fn render_response(&self) -> HttpResponse {
self.error_response()
}
}
impl From<PrepareVerifyError> for MyError {
fn from(e: PrepareVerifyError) -> Self {
MyError::Verify(e)
}
}