From ee4eb92791f43fa94b8e7d438f607a013edcb397 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Sat, 7 Dec 2024 08:59:24 -0800 Subject: [PATCH] save --- Cargo.lock | 7 ++ Cargo.toml | 2 +- rwf-auth/Cargo.toml | 7 ++ rwf-auth/migrations/.gitkeep | 0 rwf-auth/src/controllers/mod.rs | 3 + rwf-auth/src/controllers/password.rs | 101 +++++++++++++++++++++++++++ rwf-auth/src/lib.rs | 2 + rwf-auth/src/models/mod.rs | 0 rwf-auth/static/.gitkeep | 0 rwf-auth/templates/.gitkeep | 0 rwf-macros/src/render.rs | 8 +-- 11 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 rwf-auth/Cargo.toml create mode 100644 rwf-auth/migrations/.gitkeep create mode 100644 rwf-auth/src/controllers/mod.rs create mode 100644 rwf-auth/src/controllers/password.rs create mode 100644 rwf-auth/src/lib.rs create mode 100644 rwf-auth/src/models/mod.rs create mode 100644 rwf-auth/static/.gitkeep create mode 100644 rwf-auth/templates/.gitkeep diff --git a/Cargo.lock b/Cargo.lock index 40a404dd..c93c6c08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1973,6 +1973,13 @@ dependencies = [ "uuid", ] +[[package]] +name = "rwf-auth" +version = "0.1.0" +dependencies = [ + "rwf", +] + [[package]] name = "rwf-cli" version = "0.1.14" diff --git a/Cargo.toml b/Cargo.toml index 0fc48ae4..eb140543 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,6 @@ members = [ "examples/request-tracking", "examples/engine", "rwf-admin", - "examples/files", "examples/users", + "examples/files", "examples/users", "rwf-auth", ] exclude = ["examples/rails", "rwf-ruby", "examples/django", "rwf-fuzz"] diff --git a/rwf-auth/Cargo.toml b/rwf-auth/Cargo.toml new file mode 100644 index 00000000..264f6d13 --- /dev/null +++ b/rwf-auth/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rwf-auth" +version = "0.1.0" +edition = "2021" + +[dependencies] +rwf = { path = "../rwf", version = "0.2.1" } diff --git a/rwf-auth/migrations/.gitkeep b/rwf-auth/migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/rwf-auth/src/controllers/mod.rs b/rwf-auth/src/controllers/mod.rs new file mode 100644 index 00000000..322af0fe --- /dev/null +++ b/rwf-auth/src/controllers/mod.rs @@ -0,0 +1,3 @@ +// This file is automatically generated by rwf-cli. +// Manual modifications to this file will not be preserved. +pub mod password; \ No newline at end of file diff --git a/rwf-auth/src/controllers/password.rs b/rwf-auth/src/controllers/password.rs new file mode 100644 index 00000000..40ffa1f0 --- /dev/null +++ b/rwf-auth/src/controllers/password.rs @@ -0,0 +1,101 @@ +use std::marker::PhantomData; + +use rwf::{ + model::{user::Error as UserError, UserModel}, + prelude::*, +}; + +#[derive(macros::Form)] +struct PasswordForm { + identifier: String, + password: String, +} + +/// Errors passed to the template. +#[derive(macros::Context, Default)] +pub struct Errors { + /// Something was wrong with the identifier. + pub error_identifier: bool, + /// Password was incorrect or the user didn't exist. + pub error_password: bool, +} + +impl Errors { + fn form() -> Self { + let mut ctx = Self::default(); + ctx.error_identifier = true; + ctx.error_password = true; + ctx + } + + fn wrong_password() -> Self { + let mut ctx = Self::default(); + ctx.error_password = true; + ctx + } +} + +#[derive(Default)] +pub struct Password { + template_path: String, + redirect_url: String, + _marker: PhantomData, +} + +impl Password { + pub fn template(template_path: &str) -> Self { + Self { + template_path: template_path.to_owned(), + redirect_url: "/".into(), + _marker: PhantomData, + } + } + + pub fn redirect(mut self, redirect_url: &str) -> Self { + self.redirect_url = redirect_url.to_owned(); + self + } +} + +#[async_trait] +impl Controller for Password { + async fn handle(&self, request: &Request) -> Result { + PageController::handle(self, request).await + } +} + +#[async_trait] +impl PageController for Password { + async fn get(&self, request: &Request) -> Result { + render!(request, &self.template_path) + } + + async fn post(&self, request: &Request) -> Result { + let tpl = Template::load(&self.template_path)?; + + let form = if let Ok(form) = request.form::() { + form + } else { + return Ok(Response::new().html(tpl.render(Errors::form())?).code(400)); + }; + + let user = match T::create_user(&form.identifier, &form.password).await { + Ok(user) => user, + Err(UserError::UserExists) => { + match T::login_user(&form.identifier, &form.password).await { + Ok(user) => user, + Err(UserError::WrongPassword) => { + return Ok(Response::new() + .html(tpl.render(Errors::wrong_password())?) + .code(400)) + } + Err(err) => return Err(err.into()), + } + } + + Err(err) => return Err(err.into()), + }; + + Ok(request.login_user(&user)?.redirect(&self.redirect_url)) + } +} diff --git a/rwf-auth/src/lib.rs b/rwf-auth/src/lib.rs new file mode 100644 index 00000000..3619c212 --- /dev/null +++ b/rwf-auth/src/lib.rs @@ -0,0 +1,2 @@ +pub mod controllers; +pub mod models; diff --git a/rwf-auth/src/models/mod.rs b/rwf-auth/src/models/mod.rs new file mode 100644 index 00000000..e69de29b diff --git a/rwf-auth/static/.gitkeep b/rwf-auth/static/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/rwf-auth/templates/.gitkeep b/rwf-auth/templates/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/rwf-macros/src/render.rs b/rwf-macros/src/render.rs index 36c89c6d..970949f3 100644 --- a/rwf-macros/src/render.rs +++ b/rwf-macros/src/render.rs @@ -3,7 +3,7 @@ use crate::prelude::*; struct RenderInput { request: Expr, _comma_0: Token![,], - template_name: LitStr, + template_name: Expr, _comma_1: Option, context: Vec, code: Option, @@ -13,7 +13,7 @@ struct RenderInput { struct TurboStreamInput { request: Expr, _comma_0: Token![,], - template_name: LitStr, + template_name: Expr, _comma_1: Token![,], id: Expr, _comma_2: Option, @@ -38,7 +38,7 @@ impl Parse for TurboStreamInput { fn parse(input: ParseStream) -> Result { let request: Expr = input.parse()?; let _comma_0: Token![,] = input.parse()?; - let template_name: LitStr = input.parse()?; + let template_name: Expr = input.parse()?; let _comma_1: Token![,] = input.parse()?; let id: Expr = input.parse()?; let _comma_2: Option = input.parse()?; @@ -116,7 +116,7 @@ impl Parse for RenderInput { fn parse(input: ParseStream) -> Result { let request: Expr = input.parse()?; let _comma_0: Token![,] = input.parse()?; - let template_name: LitStr = input.parse()?; + let template_name: Expr = input.parse()?; let _comma_1: Option = input.parse()?; let mut code = None; let mut _comma_2 = None;