Compare commits

...

2 Commits

Author SHA1 Message Date
Matthew Pomes a885052a5b
Merge 005df63be7 into 58cebbac0b 2024-02-08 01:58:45 +04:00
Matthew Pomes 005df63be7
1/30 Update 2024-01-30 11:17:16 -06:00
2 changed files with 32 additions and 9 deletions

View File

@ -78,15 +78,29 @@ impl<'r, T: FromForm<'r>> FromData<'r> for CsrfForm<T> {
Failure((s, _e)) => return Outcome::Failure((s, CsrfError::CSRFTokenInvalid)),
Forward(()) => return Outcome::Forward(d),
};
let form: Form<CsrfTokenForm<T>> = match Form::from_data(r, d).await {
Success(t) => t,
Failure((s, e)) => return Outcome::Failure((s, CsrfError::Other(e))),
Forward(d) => return Outcome::Forward(d),
};
if token.verify(form.token).is_ok() {
Outcome::Success(Self(form.into_inner().inner))
// Bypass token in form fields if header is set
if let Some(header) = r.headers().get_one("X-CSRF-Token") {
if token.verify(header).is_ok() {
let form: Form<T> = match Form::from_data(r, d).await {
Success(t) => t,
Failure((s, e)) => return Outcome::Failure((s, CsrfError::Other(e))),
Forward(d) => return Outcome::Forward(d),
};
Outcome::Success(Self(form.into_inner()))
} else {
Outcome::Failure((Status::NotAcceptable, CsrfError::CSRFTokenInvalid))
}
} else {
Outcome::Failure((Status::NotAcceptable, CsrfError::CSRFTokenInvalid))
let form: Form<CsrfTokenForm<T>> = match Form::from_data(r, d).await {
Success(t) => t,
Failure((s, e)) => return Outcome::Failure((s, CsrfError::Other(e))),
Forward(d) => return Outcome::Forward(d),
};
if token.verify(form.token).is_ok() {
Outcome::Success(Self(form.into_inner().inner))
} else {
Outcome::Failure((Status::NotAcceptable, CsrfError::CSRFTokenInvalid))
}
}
}
}

View File

@ -7,8 +7,9 @@ use rocket::{
form::{Form, FromForm},
http::{Cookie, Status},
request::{FromRequest, Outcome},
sentinel::resolution::DefaultSentinel,
time::{Duration, OffsetDateTime},
Data, Request, Rocket, State,
Data, Request, Rocket, Sentinel, State,
};
use std::borrow::Cow;
@ -150,6 +151,14 @@ impl<'r> FromRequest<'r> for CsrfToken {
}
}
// Implement Sentinel for CsrfToken to require CsrfConfig to be attached
impl Sentinel for CsrfToken {
fn abort(rocket: &Rocket<rocket::Ignite>) -> bool {
// Delegate to `&State<CsrfConfig>`
State::<CsrfConfig>::abort(rocket)
}
}
trait RequestCsrf {
fn valid_csrf_token_from_session(&self, config: &CsrfConfig) -> Option<Vec<u8>> {
self.csrf_token_from_session(config).and_then(|raw| {