From 7d1e26af32dd2da4d4b2bfd57f48dec06ea88abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABlle=20Huisman?= Date: Fri, 13 Mar 2026 11:20:59 +0100 Subject: [PATCH] feat(dummy): add dummy method --- Cargo.lock | 10 +++ .../shield-credentials/src/provider.rs | 2 +- packages/methods/shield-dummy/Cargo.toml | 15 ++++ packages/methods/shield-dummy/README.md | 13 +++ packages/methods/shield-dummy/src/actions.rs | 5 ++ .../shield-dummy/src/actions/sign_in.rs | 86 +++++++++++++++++++ .../shield-dummy/src/actions/sign_out.rs | 55 ++++++++++++ packages/methods/shield-dummy/src/lib.rs | 5 ++ packages/methods/shield-dummy/src/method.rs | 46 ++++++++++ packages/methods/shield-dummy/src/provider.rs | 19 ++++ 10 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 packages/methods/shield-dummy/Cargo.toml create mode 100644 packages/methods/shield-dummy/README.md create mode 100644 packages/methods/shield-dummy/src/actions.rs create mode 100644 packages/methods/shield-dummy/src/actions/sign_in.rs create mode 100644 packages/methods/shield-dummy/src/actions/sign_out.rs create mode 100644 packages/methods/shield-dummy/src/lib.rs create mode 100644 packages/methods/shield-dummy/src/method.rs create mode 100644 packages/methods/shield-dummy/src/provider.rs diff --git a/Cargo.lock b/Cargo.lock index 184b30b..8fa1c88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5786,6 +5786,16 @@ dependencies = [ "shield-dioxus", ] +[[package]] +name = "shield-dummy" +version = "0.1.0" +dependencies = [ + "async-trait", + "serde", + "serde_json", + "shield", +] + [[package]] name = "shield-email" version = "0.1.0" diff --git a/packages/methods/shield-credentials/src/provider.rs b/packages/methods/shield-credentials/src/provider.rs index f764e6f..38ef51a 100644 --- a/packages/methods/shield-credentials/src/provider.rs +++ b/packages/methods/shield-credentials/src/provider.rs @@ -1,6 +1,6 @@ use shield::Provider; -use crate::CREDENTIALS_METHOD_ID; +use crate::method::CREDENTIALS_METHOD_ID; pub struct CredentialsProvider; diff --git a/packages/methods/shield-dummy/Cargo.toml b/packages/methods/shield-dummy/Cargo.toml new file mode 100644 index 0000000..2cbf4aa --- /dev/null +++ b/packages/methods/shield-dummy/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "shield-dummy" +description = "Dummy method for Shield." + +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true + +[dependencies] +async-trait.workspace = true +serde.workspace = true +serde_json.workspace = true +shield.workspace = true diff --git a/packages/methods/shield-dummy/README.md b/packages/methods/shield-dummy/README.md new file mode 100644 index 0000000..9905cb0 --- /dev/null +++ b/packages/methods/shield-dummy/README.md @@ -0,0 +1,13 @@ +

Shield Dummy

+ +Dummy method for Shield. + +## Documentation + +See [the Shield book](https://shield.rustforweb.org/) for documentation. + +## Rust for Web + +The Shield project is part of [Rust for Web](https://github.com/RustForWeb). + +[Rust for Web](https://github.com/RustForWeb) creates and ports web libraries for Rust. All projects are free and open source. diff --git a/packages/methods/shield-dummy/src/actions.rs b/packages/methods/shield-dummy/src/actions.rs new file mode 100644 index 0000000..757615c --- /dev/null +++ b/packages/methods/shield-dummy/src/actions.rs @@ -0,0 +1,5 @@ +mod sign_in; +mod sign_out; + +pub use sign_in::*; +pub use sign_out::*; diff --git a/packages/methods/shield-dummy/src/actions/sign_in.rs b/packages/methods/shield-dummy/src/actions/sign_in.rs new file mode 100644 index 0000000..5ba22c4 --- /dev/null +++ b/packages/methods/shield-dummy/src/actions/sign_in.rs @@ -0,0 +1,86 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use serde::Deserialize; +use shield::{ + Action, ActionMethod, Form, Input, InputType, InputTypeText, MethodSession, Request, Response, + ResponseType, SessionAction, ShieldError, SignInAction, Storage, User, erased_action, +}; + +use crate::provider::DummyProvider; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SignInData { + pub user_id: String, +} + +pub struct DummySignInAction { + storage: Arc>, +} + +impl DummySignInAction { + pub fn new(storage: Arc>) -> Self { + Self { storage } + } +} + +#[async_trait] +impl Action for DummySignInAction { + fn id(&self) -> String { + SignInAction::id() + } + + fn name(&self) -> String { + SignInAction::name() + } + + fn openapi_summary(&self) -> &'static str { + "Sign in with dummy" + } + + fn openapi_description(&self) -> &'static str { + "Sign in with dummy." + } + + fn method(&self) -> ActionMethod { + ActionMethod::Post + } + + async fn forms(&self, _provider: DummyProvider) -> Result, ShieldError> { + Ok(vec![Form { + inputs: vec![Input { + name: "userId".to_owned(), + label: Some("User ID".to_owned()), + r#type: InputType::Text(InputTypeText { + placeholder: Some("User ID".to_owned()), + required: Some(true), + ..Default::default() + }), + value: None, + addon_start: None, + addon_end: None, + }], + }]) + } + + async fn call( + &self, + _provider: DummyProvider, + _session: &MethodSession<()>, + request: Request, + ) -> Result { + let data = serde_json::from_value::(request.form_data) + .map_err(|err| ShieldError::Validation(err.to_string()))?; + + let user = self + .storage + .user_by_id(&data.user_id) + .await? + .ok_or_else(|| ShieldError::Validation("User not found.".to_owned()))?; + + Ok(Response::new(ResponseType::Default).session_action(SessionAction::authenticate(user))) + } +} + +erased_action!(DummySignInAction, ); diff --git a/packages/methods/shield-dummy/src/actions/sign_out.rs b/packages/methods/shield-dummy/src/actions/sign_out.rs new file mode 100644 index 0000000..b1ae478 --- /dev/null +++ b/packages/methods/shield-dummy/src/actions/sign_out.rs @@ -0,0 +1,55 @@ +use async_trait::async_trait; +use shield::{ + Action, ActionMethod, Form, MethodSession, Request, Response, ResponseType, SessionAction, + ShieldError, SignOutAction, erased_action, +}; + +use crate::provider::DummyProvider; + +pub struct DummySignOutAction; + +#[async_trait] +impl Action for DummySignOutAction { + fn id(&self) -> String { + SignOutAction::id() + } + + fn name(&self) -> String { + SignOutAction::name() + } + + fn openapi_summary(&self) -> &'static str { + "Sign out with dummy" + } + + fn openapi_description(&self) -> &'static str { + "Sign out with dummy." + } + + fn method(&self) -> ActionMethod { + ActionMethod::Post + } + + fn condition( + &self, + provider: &DummyProvider, + session: &MethodSession<()>, + ) -> Result { + SignOutAction::condition(provider, session) + } + + async fn forms(&self, provider: DummyProvider) -> Result, ShieldError> { + SignOutAction::forms(provider).await + } + + async fn call( + &self, + _provider: DummyProvider, + _session: &MethodSession<()>, + _request: Request, + ) -> Result { + Ok(Response::new(ResponseType::Default).session_action(SessionAction::Unauthenticate)) + } +} + +erased_action!(DummySignOutAction); diff --git a/packages/methods/shield-dummy/src/lib.rs b/packages/methods/shield-dummy/src/lib.rs new file mode 100644 index 0000000..5329836 --- /dev/null +++ b/packages/methods/shield-dummy/src/lib.rs @@ -0,0 +1,5 @@ +mod actions; +mod method; +mod provider; + +pub use method::*; diff --git a/packages/methods/shield-dummy/src/method.rs b/packages/methods/shield-dummy/src/method.rs new file mode 100644 index 0000000..50cf812 --- /dev/null +++ b/packages/methods/shield-dummy/src/method.rs @@ -0,0 +1,46 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use shield::{Action, Method, ShieldError, Storage, User, erased_method}; + +use crate::{ + actions::{DummySignInAction, DummySignOutAction}, + provider::DummyProvider, +}; + +pub const DUMMY_METHOD_ID: &str = "dummy"; + +pub struct DummyMethod { + storage: Arc>, +} + +impl DummyMethod { + pub fn new + 'static>(storage: S) -> Self { + Self { + storage: Arc::new(storage), + } + } +} + +#[async_trait] +impl Method for DummyMethod { + type Provider = DummyProvider; + type Session = (); + + fn id(&self) -> String { + DUMMY_METHOD_ID.to_owned() + } + + fn actions(&self) -> Vec>> { + vec![ + Box::new(DummySignInAction::new(self.storage.clone())), + Box::new(DummySignOutAction), + ] + } + + async fn providers(&self) -> Result, ShieldError> { + Ok(vec![DummyProvider]) + } +} + +erased_method!(DummyMethod, ); diff --git a/packages/methods/shield-dummy/src/provider.rs b/packages/methods/shield-dummy/src/provider.rs new file mode 100644 index 0000000..b3b2140 --- /dev/null +++ b/packages/methods/shield-dummy/src/provider.rs @@ -0,0 +1,19 @@ +use shield::Provider; + +use crate::method::DUMMY_METHOD_ID; + +pub struct DummyProvider; + +impl Provider for DummyProvider { + fn method_id(&self) -> String { + DUMMY_METHOD_ID.to_owned() + } + + fn id(&self) -> Option { + None + } + + fn name(&self) -> String { + "Dummy".to_owned() + } +}