Skip to content

Login captcha#397

Merged
freedit-dev merged 6 commits intomainfrom
login_captcha
Dec 29, 2025
Merged

Login captcha#397
freedit-dev merged 6 commits intomainfrom
login_captcha

Conversation

@freedit-dev
Copy link
Member

@freedit-dev freedit-dev commented Dec 29, 2025

Summary by CodeRabbit

  • New Features

    • Added optional login CAPTCHA authentication that administrators can enable or disable via the admin panel.
    • CAPTCHA challenge appears during login only when enabled by site configuration.
  • Localization

    • Added login CAPTCHA translations across English, French, Japanese, Ukrainian, and Simplified Chinese.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

This PR introduces a conditional login CAPTCHA feature across the application. It adds translation keys in five languages, a new boolean config flag to enable/disable CAPTCHA, passes the setting through the page rendering pipeline, makes captcha form fields optional, implements conditional captcha validation in the signin handler, and updates the admin panel and signin template to support the feature.

Changes

Cohort / File(s) Summary
Internationalization
i18n/en.toml, i18n/fr.toml, i18n/ja.toml, i18n/uk.toml, i18n/zh_cn.toml
Added login_captcha translation key with language-specific values ("Login Captcha", "Captcha de connexion", "ログインキャプチャ", "Капча входу", "登录验证码")
Configuration & Struct Definitions
src/controller/mod.rs, src/controller/admin.rs, src/controller/meta_handler.rs
Added login_captcha: bool field to SiteConfig struct with skip-validation attribute and documentation; propagated field through PageData initialization and default implementation
Authentication Logic
src/controller/user.rs
Changed FormSignin captcha fields from String to Option<String>; made captcha validation conditional on site_config.login_captcha setting; shifted site config retrieval to unconditional prior step; updated error handling for username resolution failures
Templates
templates/admin.html, templates/signin.html
Added admin radio group inputs to enable/disable login CAPTCHA; wrapped signin captcha fields in conditional block to render only when page_data.login_captcha is true

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SigninForm as Signin Form
    participant SigninHandler as Signin Handler
    participant Config as SiteConfig
    participant CaptchaService as Captcha Service
    participant AuthService as Auth Service

    User->>SigninForm: Submit credentials + optional captcha
    SigninForm->>SigninHandler: POST /signin
    SigninHandler->>Config: Fetch login_captcha setting
    
    alt login_captcha enabled
        SigninHandler->>SigninHandler: Validate captcha_id and captcha_value present
        SigninHandler->>CaptchaService: Verify captcha token
        CaptchaService-->>SigninHandler: Captcha valid/invalid
        alt Captcha invalid
            SigninHandler-->>SigninForm: Return error
        else Captcha valid
            SigninHandler->>AuthService: Validate username & password
        end
    else login_captcha disabled
        SigninHandler->>AuthService: Validate username & password
    end
    
    alt Auth successful
        AuthService-->>SigninHandler: Auth token
        SigninHandler-->>User: Redirect to dashboard
    else Auth failed
        AuthService-->>SigninHandler: Auth error
        SigninHandler-->>SigninForm: Return error
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • login captcha #394: Directly implements the same login_captcha feature with identical changes to i18n keys, SiteConfig field, PageData propagation, and signin form/template updates.
  • implement captcha on auth pages #384: Modifies the same authentication surfaces (templates/signin.html and src/controller/user.rs) for captcha handling in the signin flow.

Poem

🐰 A login guard with whiskers twitched,
"Add CAPTCHA!" cried the code-loving witch,
Translations flow, configs bloom,
Bots flee from the feature's zoom,
Security hops through the digital room!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Login captcha' directly corresponds to the main change: adding CAPTCHA functionality to the login process across configuration, templates, and internationalization files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch login_captcha

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@freedit-dev freedit-dev merged commit c0174cf into main Dec 29, 2025
5 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/controller/user.rs (2)

928-939: LGTM! Conditional CAPTCHA validation is correctly implemented.

The logic properly checks site_config.login_captcha and only validates the CAPTCHA when enabled. The early unwrapping of Option fields with ok_or(AppError::CaptchaError) provides clear error handling.

Security note: When login_captcha is disabled, the signin endpoint has no CAPTCHA protection against brute force attacks. However, the existing 1-second sleep on failed attempts (line 963) provides some mitigation. Consider documenting this trade-off for administrators in the UI or docs.


896-924: Minor inefficiency: CAPTCHA always generated regardless of setting.

The signin GET handler always creates a CAPTCHA session (line 915) even when login_captcha might be disabled. This is slightly wasteful but likely necessary for template compatibility, as the template expects captcha_id and captcha_image fields to exist.

If this causes performance concerns, consider conditionally generating the CAPTCHA based on site_config.login_captcha and updating the template to handle missing fields gracefully.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59119e9 and 6423ceb.

📒 Files selected for processing (11)
  • i18n/en.toml
  • i18n/fr.toml
  • i18n/ja.toml
  • i18n/uk.toml
  • i18n/zh_cn.toml
  • src/controller/admin.rs
  • src/controller/meta_handler.rs
  • src/controller/mod.rs
  • src/controller/user.rs
  • templates/admin.html
  • templates/signin.html
🧰 Additional context used
🧬 Code graph analysis (1)
src/controller/user.rs (3)
src/controller/mod.rs (1)
  • get (539-549)
src/controller/admin.rs (1)
  • default (363-386)
src/config.rs (1)
  • default (53-66)
🔇 Additional comments (13)
i18n/fr.toml (1)

74-74: LGTM!

The French translation for the login_captcha key is correct and consistent with the other locale additions across the PR.

i18n/ja.toml (1)

74-74: LGTM!

The Japanese translation for the login_captcha key is appropriate and aligns with the feature implementation.

i18n/zh_cn.toml (1)

75-75: LGTM!

The Chinese translation for the login_captcha key is accurate and consistent with the multilingual support for this feature.

i18n/en.toml (1)

74-74: LGTM!

The English translation key is correctly added and serves as the base for the other locale translations.

i18n/uk.toml (1)

75-75: LGTM!

The Ukrainian translation for the login_captcha key is correct and completes the multilingual support for this feature.

src/controller/meta_handler.rs (2)

171-171: LGTM!

The login_captcha field addition to PageData<'a> with pub(super) visibility is appropriate for exposing the configuration to templates within the controller module.


198-198: LGTM!

The initialization of login_captcha from site_config.login_captcha correctly propagates the configuration setting to the page data for template rendering.

templates/admin.html (1)

286-303: LGTM!

The admin UI implementation for the login_captcha configuration correctly uses conditional rendering to ensure the appropriate radio button is checked based on the current site_config.login_captcha value. The form will submit string values ("true" or "false"), which the backend should parse appropriately.

templates/signin.html (1)

31-43: Backend correctly handles optional CAPTCHA fields.

The FormSignin struct properly defines captcha_id and captcha_value as Option<String> fields, allowing them to be absent when CAPTCHA is disabled. The signin_post handler conditionally validates these fields only when site_config.login_captcha is enabled, using .ok_or() to enforce their presence in that case. The template's conditional rendering and required attribute are correctly aligned with this backend behavior.

src/controller/admin.rs (1)

362-386: LGTM! Default initialization is correct.

The login_captcha field is properly initialized to false in the Default implementation, making the login CAPTCHA feature opt-in. This ensures backward compatibility for existing deployments.

src/controller/mod.rs (1)

532-534: LGTM! Configuration field is well-defined.

The login_captcha field is properly documented and follows the established pattern for SiteConfig fields. The #[validate(skip)] attribute is appropriate for a boolean configuration flag.

src/controller/user.rs (2)

880-881: LGTM! Optional fields enable conditional CAPTCHA flow.

Changing captcha_id and captcha_value to Option<String> correctly supports the conditional CAPTCHA feature. When login_captcha is disabled, these fields won't be present in the form submission.


941-944: Excellent security improvement: prevents username enumeration.

Changing the error from AppError::NotFound to AppError::WrongPassword when username lookup fails prevents attackers from determining which usernames exist in the system. This is a security best practice for authentication flows.

@freedit-dev freedit-dev deleted the login_captcha branch December 29, 2025 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant