#![feature(decl_macro)] #[macro_use] extern crate rocket; #[macro_use] extern crate serde_derive; use rocket::response::{Flash, Redirect}; use rocket::request::{FlashMessage, Form}; use rocket_contrib::templates::Template; use rocket_csrf::CsrfToken; #[derive(Serialize)] struct TemplateContext { authenticity_token: String, flash: Option, } #[derive(FromForm)] struct Comment { authenticity_token: String, text: String, } fn main() { rocket::ignite() .attach(rocket_csrf::Fairing::new()) .attach(Template::fairing()) .mount("/", routes![index, new, create]) .launch(); } #[get("/")] fn index() -> Redirect { Redirect::to(uri!(new)) } #[get("/comments/new")] fn new(csrf_token: CsrfToken, flash: Option) -> Template { let template_context = TemplateContext { authenticity_token: csrf_token.0, flash: flash.map(|msg| format!("{}! {}", msg.name(), msg.msg())), }; Template::render("comments/new", &template_context) } #[post("/comments", data = "
")] fn create(csrf_token: CsrfToken, form: Form) -> Flash { if let Err(_) = csrf_token.verify(&form.authenticity_token) { return Flash::error( Redirect::to(uri!(new)), "invalid authenticity token", ); } Flash::success( Redirect::to(uri!(new)), format!("created comment: {:#?}", form.text), ) }