1
0
Fork 0

Verify CSRF token

This commit is contained in:
Alex Kotov 2020-10-17 02:19:12 +05:00
parent 2dcf267893
commit 8dcf5261b1
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
3 changed files with 58 additions and 5 deletions

View File

@ -15,12 +15,27 @@ pub struct Fairing;
pub struct Guard(pub String);
pub struct VerificationFailure;
impl Fairing {
pub fn new() -> Self {
Self {}
}
}
impl Guard {
pub fn verify(&self, form_authenticity_token: &String)
-> Result<(), VerificationFailure>
{
if self.0 == *form_authenticity_token {
Ok(())
}
else {
Err(VerificationFailure {})
}
}
}
impl RocketFairing for Fairing {
fn info(&self) -> Info {
Info {

View File

@ -32,6 +32,8 @@ pub fn create(
form: Form<forms::UserSignIn>,
mut cookies: Cookies,
) -> Result<Redirect, UserSignInResponse> {
csrf.verify(&form.authenticity_token)?;
if let Some(_) = current_user.0 {
return Err(UserSignInResponse::AlreadySignedIn(
Redirect::to(uri!(super::home::index))
@ -54,15 +56,19 @@ pub fn create(
Ok(Redirect::to(uri!(super::home::index)))
}
#[delete("/sign_out", data = "<_form>")]
#[delete("/sign_out", data = "<form>")]
pub fn delete(
_csrf: csrf::Guard,
csrf: csrf::Guard,
current_user: states::MaybeCurrentUser,
_form: Form<forms::UserSignOut>,
form: Form<forms::UserSignOut>,
mut cookies: Cookies,
) -> Result<Redirect, Redirect> {
) -> Result<Redirect, UserSignOutResponse> {
csrf.verify(&form.authenticity_token)?;
if let None = current_user.0 {
return Err(Redirect::to(uri!(super::home::index)));
return Err(UserSignOutResponse::NoUserSignedIn(
Redirect::to(uri!(super::home::index))
));
}
cookies.remove_private(Cookie::named("user_id"));
@ -74,12 +80,22 @@ pub fn delete(
#[response(content_type = "text/html")]
pub enum UserSignInResponse {
AlreadySignedIn(Redirect),
#[response(status = 403)]
InvalidAuthenticityToken(()),
#[response(status = 422)]
InvalidCredentials(Template),
#[response(status = 500)]
UnknownError(()),
}
#[derive(Debug, rocket::response::Responder)]
#[response(context_type = "text/html")]
pub enum UserSignOutResponse {
NoUserSignedIn(Redirect),
#[response(status = 403)]
InvalidAuthenticityToken(()),
}
#[derive(Serialize)]
struct BasicTemplateContext {
csrf_token: String,
@ -91,3 +107,15 @@ impl From<diesel::result::Error> for UserSignInResponse {
Self::UnknownError(())
}
}
impl From<csrf::VerificationFailure> for UserSignInResponse {
fn from(_: csrf::VerificationFailure) -> UserSignInResponse {
Self::InvalidAuthenticityToken(())
}
}
impl From<csrf::VerificationFailure> for UserSignOutResponse {
fn from(_: csrf::VerificationFailure) -> UserSignOutResponse {
Self::InvalidAuthenticityToken(())
}
}

View File

@ -32,6 +32,8 @@ pub fn create(
form: Form<forms::UserSignUp>,
mut cookies: Cookies,
) -> Result<Redirect, UserSignUpResponse> {
csrf.verify(&form.authenticity_token)?;
if let Some(_) = current_user.0 {
return Err(UserSignUpResponse::AlreadySignedIn(
Redirect::to(uri!(super::home::index))
@ -51,6 +53,8 @@ pub fn create(
#[response(content_type = "text/html")]
pub enum UserSignUpResponse {
AlreadySignedIn(Redirect),
#[response(status = 403)]
InvalidAuthenticityToken(()),
#[response(status = 422)]
InvalidForm(Template),
#[response(status = 500)]
@ -97,3 +101,9 @@ impl From<diesel::result::Error> for UserSignUpResponse {
Self::UnknownError(())
}
}
impl From<csrf::VerificationFailure> for UserSignUpResponse {
fn from(_: csrf::VerificationFailure) -> Self {
Self::InvalidAuthenticityToken(())
}
}