diff --git a/Cargo.toml b/Cargo.toml index eae336c..6e34966 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rocket_csrf" -version = "0.3.0" +version = "0.4.0-rc.1" authors = ["Alex Kotov "] edition = "2018" description = "CSRF (Cross-Site Request Forgery) protection for Rocket web framework" @@ -16,5 +16,5 @@ publish = true base64 = { version = "0.13.0" } bcrypt = { version = "0.9" } rand = { version = "0.8.3" } -rocket = { version = "0.4.5", features = ["private-cookies"] } -time = { version = "0.1.38" } +rocket = { version = "0.5.0-rc.1", features = ["secrets"] } +time = { version = "0.2.25" } diff --git a/src/lib.rs b/src/lib.rs index 86bf72a..8e20df8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,14 @@ use bcrypt::{hash, verify}; use rand::{distributions::Standard, Rng}; use rocket::{ - fairing::{Fairing as RocketFairing, Info, Kind}, + async_trait, + fairing::{self, Fairing as RocketFairing, Info, Kind}, http::{Cookie, Status}, request::{FromRequest, Outcome}, Data, Request, Rocket, State, }; use std::borrow::Cow; -use time::Duration; +use time::{Duration, OffsetDateTime}; const BCRYPT_COST: u32 = 8; @@ -94,20 +95,21 @@ impl CsrfToken { } } +#[async_trait] impl RocketFairing for Fairing { fn info(&self) -> Info { Info { name: "CSRF", - kind: Kind::Attach | Kind::Request, + kind: Kind::Ignite | Kind::Request, } } - fn on_attach(&self, rocket: Rocket) -> std::result::Result { + async fn on_ignite(&self, rocket: Rocket) -> fairing::Result { Ok(rocket.manage(self.config.clone())) } - fn on_request(&self, request: &mut Request, _: &Data) { - let config = request.guard::>().unwrap(); + async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) { + let config = request.guard::<&State>().await.unwrap(); if let Some(_) = request.valid_csrf_token_from_session(&config) { return; @@ -120,7 +122,7 @@ impl RocketFairing for Fairing { let encoded = base64::encode(&values[..]); - let expires = time::now_utc() + config.lifespan; + let expires = OffsetDateTime::now_utc() + config.lifespan; request.cookies().add_private( Cookie::build(config.cookie_name.clone(), encoded) @@ -130,11 +132,12 @@ impl RocketFairing for Fairing { } } -impl<'a, 'r> FromRequest<'a, 'r> for CsrfToken { +#[async_trait] +impl<'r> FromRequest<'r> for CsrfToken { type Error = (); - fn from_request(request: &'a Request<'r>) -> Outcome { - let config = request.guard::>().unwrap(); + async fn from_request(request: &'r Request<'_>) -> Outcome { + let config = request.guard::<&State>().await.unwrap(); match request.valid_csrf_token_from_session(&config) { None => Outcome::Failure((Status::Forbidden, ())), diff --git a/tests/fairing_configured.rs b/tests/fairing_configured.rs index a7b4a5a..b287ea7 100644 --- a/tests/fairing_configured.rs +++ b/tests/fairing_configured.rs @@ -1,17 +1,15 @@ -#![feature(decl_macro)] - #[macro_use] extern crate rocket; const COOKIE_NAME: &str = "foobar"; const COOKIE_LEN: usize = 64; -fn client() -> rocket::local::Client { - rocket::local::Client::new(rocket()).unwrap() +fn client() -> rocket::local::blocking::Client { + rocket::local::blocking::Client::tracked(rocket()).unwrap() } -fn rocket() -> rocket::Rocket { - rocket::ignite() +fn rocket() -> rocket::Rocket { + rocket::build() .attach(rocket_csrf::Fairing::new( rocket_csrf::CsrfConfig::default() .with_cookie_name(COOKIE_NAME) diff --git a/tests/fairing_default.rs b/tests/fairing_default.rs index 00d7d8a..835a63e 100644 --- a/tests/fairing_default.rs +++ b/tests/fairing_default.rs @@ -1,14 +1,12 @@ -#![feature(decl_macro)] - #[macro_use] extern crate rocket; -fn client() -> rocket::local::Client { - rocket::local::Client::new(rocket()).unwrap() +fn client() -> rocket::local::blocking::Client { + rocket::local::blocking::Client::tracked(rocket()).unwrap() } -fn rocket() -> rocket::Rocket { - rocket::ignite() +fn rocket() -> rocket::Rocket { + rocket::build() .attach(rocket_csrf::Fairing::default()) .mount("/", routes![index]) } diff --git a/tests/guard_configured.rs b/tests/guard_configured.rs index 89c31ee..295e8d0 100644 --- a/tests/guard_configured.rs +++ b/tests/guard_configured.rs @@ -1,5 +1,3 @@ -#![feature(decl_macro)] - #[macro_use] extern crate rocket; @@ -11,12 +9,12 @@ use rocket_csrf::CsrfToken; const COOKIE_NAME: &str = "foobar"; const COOKIE_LEN: usize = 64; -fn client() -> rocket::local::Client { - rocket::local::Client::new(rocket()).unwrap() +fn client() -> rocket::local::blocking::Client { + rocket::local::blocking::Client::tracked(rocket()).unwrap() } -fn rocket() -> rocket::Rocket { - rocket::ignite() +fn rocket() -> rocket::Rocket { + rocket::build() .attach(rocket_csrf::Fairing::new( rocket_csrf::CsrfConfig::default() .with_cookie_name(COOKIE_NAME) @@ -42,8 +40,6 @@ fn respond_with_valid_authenticity_token() { .get("/") .private_cookie(Cookie::new(COOKIE_NAME, encoded.to_string())) .dispatch() - .body() - .unwrap() .into_string() .unwrap(); diff --git a/tests/guard_default.rs b/tests/guard_default.rs index af80a29..3e24746 100644 --- a/tests/guard_default.rs +++ b/tests/guard_default.rs @@ -1,5 +1,3 @@ -#![feature(decl_macro)] - #[macro_use] extern crate rocket; @@ -8,12 +6,12 @@ use rand::RngCore; use rocket::http::Cookie; use rocket_csrf::CsrfToken; -fn client() -> rocket::local::Client { - rocket::local::Client::new(rocket()).unwrap() +fn client() -> rocket::local::blocking::Client { + rocket::local::blocking::Client::tracked(rocket()).unwrap() } -fn rocket() -> rocket::Rocket { - rocket::ignite() +fn rocket() -> rocket::Rocket { + rocket::build() .attach(rocket_csrf::Fairing::default()) .mount("/", routes![index]) } @@ -34,8 +32,6 @@ fn respond_with_valid_authenticity_token() { .get("/") .private_cookie(Cookie::new("csrf_token", encoded.to_string())) .dispatch() - .body() - .unwrap() .into_string() .unwrap();