http-signature-normalization/http-signature-normalization-actix/examples/server.rs

99 lines
2.4 KiB
Rust
Raw Normal View History

2020-03-30 05:53:45 +00:00
use actix_web::{
http::StatusCode, middleware::Logger, web, App, HttpRequest, HttpResponse, HttpServer,
ResponseError,
};
use futures::future::{err, ok, Ready};
use http_signature_normalization_actix::prelude::*;
use log::info;
2019-09-13 01:12:35 +00:00
use sha2::{Digest, Sha256};
2019-09-11 23:06:36 +00:00
#[derive(Clone, Debug)]
struct MyVerify;
2019-09-11 23:06:36 +00:00
impl SignatureVerify for MyVerify {
type Error = MyError;
type Future = Ready<Result<bool, Self::Error>>;
fn signature_verify(
&mut self,
algorithm: Option<Algorithm>,
key_id: String,
signature: String,
signing_string: String,
) -> Self::Future {
match algorithm {
Some(Algorithm::Hs2019) => (),
_ => return err(MyError::Algorithm),
};
2019-09-13 23:12:12 +00:00
if key_id != "my-key-id" {
return err(MyError::Key);
2019-09-13 23:12:12 +00:00
}
let decoded = match base64::decode(&signature) {
Ok(decoded) => decoded,
Err(_) => return err(MyError::Decode),
};
2019-09-11 23:06:36 +00:00
println!("Signing String\n{}", signing_string);
ok(decoded == signing_string.as_bytes())
2019-09-11 23:06:36 +00:00
}
}
async fn index(
(_, sig_verified): (DigestVerified, SignatureVerified),
req: HttpRequest,
2020-03-25 16:00:37 +00:00
_body: web::Bytes,
) -> &'static str {
info!("Verified request for {}", sig_verified.key_id());
info!("{:?}", req);
"Eyyyyup"
}
#[actix_rt::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
std::env::set_var("RUST_LOG", "info");
pretty_env_logger::init();
let config = Config::default().require_header("accept").require_digest();
2019-09-11 23:06:36 +00:00
HttpServer::new(move || {
App::new()
.wrap(VerifyDigest::new(Sha256::new()).optional())
.wrap(VerifySignature::new(MyVerify, config.clone()).optional())
2020-03-30 05:53:45 +00:00
.wrap(Logger::default())
2019-09-13 01:12:35 +00:00
.route("/", web::post().to(index))
2019-09-11 23:06:36 +00:00
})
.bind("127.0.0.1:8010")?
.run()
.await?;
2019-09-11 23:06:36 +00:00
Ok(())
}
#[derive(Debug, thiserror::Error)]
2019-09-11 23:06:36 +00:00
enum MyError {
#[error("Failed to verify, {0}")]
Verify(#[from] PrepareVerifyError),
2019-09-11 23:06:36 +00:00
#[error("Unsupported algorithm")]
2019-09-13 01:29:24 +00:00
Algorithm,
#[error("Couldn't decode signature")]
Decode,
2019-09-13 23:12:12 +00:00
#[error("Invalid key")]
2019-09-13 23:12:12 +00:00
Key,
2019-09-11 23:06:36 +00:00
}
impl ResponseError for MyError {
fn status_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
fn error_response(&self) -> HttpResponse {
HttpResponse::BadRequest().finish()
2019-09-11 23:06:36 +00:00
}
}