Skip to content

fix(auth): restore password helper compatibility and prevent API restart loop

Praneeth Ashish requested to merge fix/password-function-import-error into develop

Merge Request

Overview

This MR fixes an authentication regression that caused startup failures and Docker restart loops. Compared with develop, this branch contains one commit and one file change focused on password utility compatibility and resilience.

What does this MR do and why?

fix(auth): restore password helper compatibility to prevent restart loop

The motivation was to resolve runtime import and compatibility issues in auth password handling and stabilize validation flows for edge-case hash inputs. The approach was to replace passlib context usage with a minimal bcrypt-based wrapper while preserving the existing interface expected by the rest of the codebase. Trade-off: this keeps behavior stable for current callers without broader auth refactors, and does not address unrelated project-wide deprecation warnings.

Changes Made

  • Modified app/utils/password_utils.py
  • Replaced passlib CryptContext usage with a bcrypt-backed PasswordContext wrapper
  • Added get_password_hash alias for backward compatibility
  • Updated verify_password signature to accept nullable hash input
  • Added defensive handling for empty or invalid hashes to return false instead of raising
  • Added explicit type casts to satisfy mypy checks

Technical Details

Root cause:

  • Auth flows expected compatibility around get_password_hash and verification behavior.
  • Password utility implementation drift caused import/runtime instability and fragile handling of invalid hash inputs.

How this fix addresses it:

  • Introduces a stable context-compatible wrapper (hash and verify) over bcrypt.
  • Restores get_password_hash symbol compatibility.
  • Hardens verify_password against None, empty, and invalid hash values.
  • Keeps typing strict and hook-compliant (Ruff and mypy).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📝 Documentation update
  • ️ Refactor (no functional changes)
  • Performance improvement
  • 🧪 Test update
  • 🔧 Configuration change
  • 🚨 Security fix
  • 🗑️ Deprecation (removing deprecated code)

Related Issues / References

#83 (closed)

Screenshots or Screen Recordings

Please Refer Comments

How to Validate Locally

  1. Checkout this branch and install dependencies.
  2. Run lint and type checks.
  3. Run auth-focused tests.
  4. Run full test suite with coverage.
  5. Start the API and verify no restart loop from password utility issues.

Testing Done

  • Unit tests added/updated
  • API endpoint tests passing

Test Cases Covered:

Scenario Expected Result Status
get_password_hash compatibility Auth import and call paths work
verify_password with empty hash Returns false, no crash
verify_password with None hash Returns false, no crash
verify_password with invalid hash Returns false, no crash
Auth service valid password path User authenticates successfully
Auth service invalid password path Authentication rejected
Forgot-password with book number Password reset route succeeds with valid OTP
Full test suite No failures

Test Commands Run:

uv run ruff check app/utils/password_utils.py
uv run mypy app/utils/password_utils.py
uv run pytest tests/test_services/test_auth_service.py tests/test_api/test_auth_routes.py -q
uv run pytest --cov=app tests/ -q

Code Quality Checklist

Code Standards

  • Code follows project conventions (naming, structure, formatting)
  • No debug statements or commented-out code left (unless necessary and intended)
  • No unused imports, variables, or functions
  • No duplicate code (DRY principle followed)
  • Type hints are properly defined (no Any unless justified and no mypy type check errors)
  • Ruff checks pass:
    ruff check .
    ruff format . --check

Python & FastAPI Best Practices

  • Functions follow single-responsibility principle
  • Async/await used correctly (no blocking calls in async functions)
  • Dependency injection used appropriately
  • Pydantic models used for request/response validation
  • SQLAlchemy queries are optimized (no N+1 queries)
  • Error handling is comprehensive (try/except with proper logging)

API Design

  • RESTful conventions followed
  • Proper HTTP status codes returned
  • Input validation implemented
  • Authentication/authorization enforced
  • Role Base access control used for user restriction
  • API documentation (docstrings) updated

Database & Migrations

  • Database migrations created (if schema changed)
  • Database migrations version is pointing to the latest version (and version name follows project conventions)
  • Migrations are reversible (migrations contain downgrade scripts)
  • Indexes added for frequently queried fields
  • No raw SQL queries (using SQLAlchemy ORM)
  • Data integrity constraints maintained

Security

  • No sensitive data logged (passwords, tokens, PII)
  • SQL injection prevention verified (ORM used)
  • Input sanitization implemented
  • Authentication tokens handled securely
  • CORS settings appropriate
  • Security scan passes:
    bandit -r app/

Error Handling

  • Errors are caught and handled gracefully
  • User-friendly error messages returned
  • Errors are logged appropriately
  • HTTP error responses follow API standards

Documentation

  • README.md updated (if setup steps changed)
  • .env.example updated (if new env vars added)
  • API documentation updated (docstrings, OpenAPI specs)
  • CHANGELOG.md will be updated (if applicable)
  • Code comments explain complex logic (not what, but why)

Known Limitations / Technical Debt

  • This MR intentionally focuses on password utility compatibility and robustness only.
  • Existing unrelated deprecation warnings remain out of scope.

Additional Notes

  • Diff versus develop includes:
  • 1 commit: fix(auth): restore password helper compatibility to prevent restart loop
  • 1 modified file: app/utils/password_utils.py

MR Acceptance Checklist

Quality & Correctness

  • Code works as intended and solves the stated problem
  • No bugs introduced (existing functionality not broken)
  • Edge cases handled appropriately

Maintainability

  • Code is readable and well-organized
  • Code is testable and well-tested
  • Follows project patterns and conventions

Acceptance Review

  • Reviewed by at least 1 teammate
  • Reviewed by product owner
Edited by Praneeth Ashish

Merge request reports

Loading