Compare commits

...

5 commits

Author SHA1 Message Date
4ce55e73f0
chore: Bump the version to 0.3.0
Some checks failed
Rust CI / Rust CI (push) Failing after 48s
Signed-off-by: Awiteb <a@4rs.nl>
2024-08-12 21:08:14 +00:00
3b957ccfc5
chore: Update README.md
Signed-off-by: Awiteb <a@4rs.nl>
2024-08-12 21:07:55 +00:00
c1e6a76a79
chore!: Rename simple_generator feature to simple-generator
Signed-off-by: Awiteb <a@4rs.nl>
2024-08-12 21:06:32 +00:00
ae832194e7
chore: Bump the version to 0.2.0
Some checks failed
Rust CI / Rust CI (push) Failing after 49s
Signed-off-by: Awiteb <a@4rs.nl>
2024-08-12 20:44:21 +00:00
dab2db43cf
docs: Improve the docs
Some checks failed
Rust CI / Rust CI (push) Failing after 50s
Signed-off-by: Awiteb <a@4rs.nl>
2024-08-12 20:43:14 +00:00
9 changed files with 34 additions and 14 deletions

View file

@ -18,7 +18,7 @@ jobs:
- name: Build the source code - name: Build the source code
run: cargo build run: cargo build
- name: Build examples - name: Build examples
run: cargo build -F 'cacache-storage' --example simple_login run: cargo build -F 'simple-generator' --example simple_login
- name: Run tests - name: Run tests
run: cargo test --tests --all-features run: cargo test --tests --all-features
- name: Check the code format - name: Check the code format

View file

@ -1,6 +1,6 @@
[package] [package]
name = "salvo-captcha" name = "salvo-captcha"
version = "0.1.0" version = "0.3.0"
rust-version = "1.75.0" rust-version = "1.75.0"
edition = "2021" edition = "2021"
authors = ["Awiteb <a@4rs.nl>"] authors = ["Awiteb <a@4rs.nl>"]
@ -35,4 +35,4 @@ rstest = "0.22.0"
[[example]] [[example]]
name = "simple_login" name = "simple_login"
required-features = ["simple_generator"] required-features = ["simple-generator"]

View file

@ -19,7 +19,7 @@ _default:
# Run the CI (Local use only) # Run the CI (Local use only)
@ci: @ci:
cargo fmt --all --check cargo fmt --all --check
cargo build -F 'simple_generator' --example simple_login cargo build -F 'simple-generator' --example simple_login
cargo clippy --workspace --all-targets --examples --tests --all-features -- -D warnings cargo clippy --workspace --all-targets --examples --tests --all-features -- -D warnings
cargo nextest run --workspace --all-targets --all-features cargo nextest run --workspace --all-targets --all-features
@{{JUST_EXECUTABLE}} msrv @{{JUST_EXECUTABLE}} msrv

View file

@ -46,7 +46,14 @@ We provide fully customizable query parameters, form fields, and headers to find
## Captcha Generator ## Captcha Generator
We provide [`SimpleCaptchaGenerator`] which is a simple captcha generator based on the [`captcha`] crate. You can implement your own captcha generator by implementing the [`CaptchaGenerator`] trait. We provide [`SimpleCaptchaGenerator`] which is a simple captcha generator based on the [`captcha`] crate, you can enable it by enabling the `simple-generator` feature.
```toml
[dependencies]
salvo-captcha = { version = "0.2", features = ["simple-generator"] }
```
You can implement your own generator by implementing the [`CaptchaGenerator`] trait.
### Captcha name and difficulty ### Captcha name and difficulty

View file

@ -9,10 +9,10 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#[cfg(feature = "simple_generator")] #[cfg(feature = "simple-generator")]
mod simple_generator; mod simple_generator;
#[cfg(feature = "simple_generator")] #[cfg(feature = "simple-generator")]
pub use simple_generator::*; pub use simple_generator::*;
/// Captcha generator, used to generate a new captcha image and answer. /// Captcha generator, used to generate a new captcha image and answer.

View file

@ -76,7 +76,7 @@ impl Display for SimpleGeneratorError {
impl std::error::Error for SimpleGeneratorError {} impl std::error::Error for SimpleGeneratorError {}
/// The simple captcha generator /// A simple captcha generator, using the [`captcha`](https://crates.io/crates/captcha) crate.
pub struct SimpleGenerator { pub struct SimpleGenerator {
name: CaptchaName, name: CaptchaName,
difficulty: CaptchaDifficulty, difficulty: CaptchaDifficulty,
@ -93,8 +93,6 @@ impl CaptchaGenerator for SimpleGenerator {
type Error = SimpleGeneratorError; type Error = SimpleGeneratorError;
/// The returned captcha image is 220x110 pixels in png format. /// The returned captcha image is 220x110 pixels in png format.
///
/// For more information about the captcha name and difficulty, see the [`README.md`](https://git.4rs.nl/awiteb/salvo-captcha/#captcha-name-and-difficulty).
async fn new_captcha(&self) -> Result<(String, Vec<u8>), Self::Error> { async fn new_captcha(&self) -> Result<(String, Vec<u8>), Self::Error> {
let Some((captcha_answer, captcha_image)) = let Some((captcha_answer, captcha_image)) =
captcha::by_name(self.difficulty.into(), self.name.into()).as_tuple() captcha::by_name(self.difficulty.into(), self.name.into()).as_tuple()

View file

@ -29,7 +29,21 @@ pub use {captcha_gen::*, finder::*, storage::*};
/// Key used to insert the captcha state into the depot /// Key used to insert the captcha state into the depot
pub const CAPTCHA_STATE_KEY: &str = "::salvo_captcha::captcha_state"; pub const CAPTCHA_STATE_KEY: &str = "::salvo_captcha::captcha_state";
/// Captcha struct, contains the token and answer. /// The captcha middleware
///
/// The captcha middleware is used to check the captcha token and answer from
/// the request. You can use the [`CaptchaBuilder`] to create a new captcha
/// middleware.
///
/// ## Note
/// You need to generate the captcha token and answer before, then the captcha
/// middleware will check the token and answer from the request using the finder
/// and storage you provided. The captcha middleware will insert the
/// [`CaptchaState`] into the depot, you can get the captcha state from the
/// depot using the [`CaptchaDepotExt::get_captcha_state`] trait, which is
/// implemented for the [`Depot`].
///
/// Check the [`examples`](https://git.4rs.nl/awiteb/salvo-captcha/src/branch/master/examples) for more information.
#[non_exhaustive] #[non_exhaustive]
pub struct Captcha<S, F> pub struct Captcha<S, F>
where where

View file

@ -16,7 +16,7 @@ use std::{
use crate::CaptchaStorage; use crate::CaptchaStorage;
/// The [`cacache`] storage. /// The [`cacache`] storage. Store the token and answer in the disk.
/// ///
/// [`cacache`]: https://github.com/zkat/cacache-rs /// [`cacache`]: https://github.com/zkat/cacache-rs
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -26,7 +26,7 @@ pub struct CacacheStorage {
} }
impl CacacheStorage { impl CacacheStorage {
/// Create a new CacacheStorage /// Create a new [`CacacheStorage`] instance with the cache directory.
pub fn new(cache_dir: impl Into<PathBuf>) -> Self { pub fn new(cache_dir: impl Into<PathBuf>) -> Self {
Self { Self {
cache_dir: cache_dir.into(), cache_dir: cache_dir.into(),

View file

@ -20,7 +20,7 @@ use tokio::sync::RwLock;
use crate::CaptchaStorage; use crate::CaptchaStorage;
/// Captcha storage implementation using an in-memory HashMap. /// Captcha storage implementation using an in-memory [HashMap].
#[derive(Debug)] #[derive(Debug)]
pub struct MemoryStorage(RwLock<HashMap<String, (u64, String)>>); pub struct MemoryStorage(RwLock<HashMap<String, (u64, String)>>);
@ -32,6 +32,7 @@ impl MemoryStorage {
} }
impl CaptchaStorage for MemoryStorage { impl CaptchaStorage for MemoryStorage {
/// This storage does not return any error.
type Error = Infallible; type Error = Infallible;
async fn store_answer(&self, answer: String) -> Result<String, Self::Error> { async fn store_answer(&self, answer: String) -> Result<String, Self::Error> {