Skip to content

fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore#12

Merged
parkcheolhong merged 2 commits intomainfrom
copilot/fix-health-check-error-exposure
May 8, 2026
Merged

fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore#12
parkcheolhong merged 2 commits intomainfrom
copilot/fix-health-check-error-exposure

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 8, 2026

Five auth router tests were crashing with ModuleNotFoundError: No module named 'webauthn', and datetime.utcnow() deprecation warnings were firing across auth code on Python 3.12+. No .gitignore existed, so __pycache__ artifacts had been committed.

Changes

  • tests/test_auth_router_security.py_load_auth_router() now stubs webauthn and webauthn.helpers.structs into sys.modules before importing backend.auth_router, matching the existing pattern for backend.database/backend.models
  • backend/auth_router.py, backend/auth.py – Replace all datetime.utcnow() with datetime.now(timezone.utc); add timezone to imports. Comparison and creation are now both timezone-aware, eliminating mixed-aware/naive TypeError risk
  • backend/auth_router.py – Replace deprecated Pydantic v1-style class Config: from_attributes = True on UserResponse with model_config = ConfigDict(from_attributes=True)
  • .gitignore – Add standard Python .gitignore; remove previously tracked __pycache__/*.pyc entries from the git index
# before
fake_models.User = _StubUser
monkeypatch.setitem(sys.modules, "backend.database", fake_database)
monkeypatch.setitem(sys.modules, "backend.models", fake_models)

# after – webauthn stubbed so auth_router can be imported without the package
monkeypatch.setitem(sys.modules, "webauthn", _stub_webauthn)
monkeypatch.setitem(sys.modules, "webauthn.helpers", _stub_helpers)
monkeypatch.setitem(sys.modules, "webauthn.helpers.structs", _stub_structs)
monkeypatch.setitem(sys.modules, "backend.database", fake_database)
monkeypatch.setitem(sys.modules, "backend.models", fake_models)

Summary by Sourcery

Ensure authentication flows and tests use timezone-aware datetimes and work without the optional WebAuthn dependency, while aligning the auth router model with Pydantic v2 configuration and ignoring Python build artifacts in version control.

Bug Fixes:

  • Stub the optional WebAuthn module and its helper structs in auth router tests so they run without the webauthn package installed.
  • Replace uses of datetime.utcnow() in auth and auth router logic with timezone-aware UTC datetimes to avoid deprecation warnings and mixed-aware/naive datetime issues.

Enhancements:

  • Update the UserResponse Pydantic model to use ConfigDict-based configuration compatible with Pydantic v2.

Build:

  • Add a Python-focused .gitignore to exclude pycache and other generated artifacts from version control.

Tests:

  • Adjust auth router tests to use timezone-aware expiration timestamps consistent with the application code.

Copilot AI and others added 2 commits May 8, 2026 12:50
…nfig, add .gitignore

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 8, 2026

Reviewer's Guide

Makes auth tests resilient to missing optional webauthn dependency, standardizes all auth-related datetime handling to timezone-aware usage, updates a Pydantic model to v2-style configuration, and adds a Python-focused .gitignore to stop tracking bytecode artifacts.

Sequence diagram for auth router import with webauthn stubs in tests

sequenceDiagram
    actor Pytest
    participant TestAuthRouterSecurity
    participant SysModules
    participant WebauthnStub
    participant BackendAuthRouter

    Pytest->>TestAuthRouterSecurity: run _load_auth_router
    TestAuthRouterSecurity->>WebauthnStub: create _stub_webauthn, _stub_helpers, _stub_structs
    TestAuthRouterSecurity->>SysModules: setitem webauthn = _stub_webauthn
    TestAuthRouterSecurity->>SysModules: setitem webauthn.helpers = _stub_helpers
    TestAuthRouterSecurity->>SysModules: setitem webauthn.helpers.structs = _stub_structs
    TestAuthRouterSecurity->>SysModules: setitem backend.database = fake_database
    TestAuthRouterSecurity->>SysModules: setitem backend.models = fake_models
    TestAuthRouterSecurity->>BackendAuthRouter: import backend.auth_router
    BackendAuthRouter->>SysModules: import webauthn and webauthn.helpers.structs
    SysModules-->>BackendAuthRouter: return stubbed modules
    BackendAuthRouter-->>TestAuthRouterSecurity: loaded auth router without real webauthn
    TestAuthRouterSecurity-->>Pytest: continue running auth tests
Loading

Updated class diagram for auth models using timezone-aware datetimes and Pydantic v2 ConfigDict

classDiagram
    class BaseModel

    class UserResponse {
        +int id
        +str email
        +Optional[str] name
        +Optional[str] business_registration_number
        +Optional[str] representative_name
        +ConfigDict model_config
    }

    class Token {
        +str access_token
        +str token_type
    }

    BaseModel <|-- UserResponse
    BaseModel <|-- Token

    class AuthRouterInternal {
        +tuple~str, datetime~ _issue_recovery_token(prefix)
        +None _purge_expired_password_recovery_sessions()
        +None start_passkey_registration(user, payload, db)
        +None finish_passkey_registration(payload, db)
        +None start_passkey_login(user)
        +None finish_passkey_login(payload, db)
        +None verify_password_recovery_identity(payload, db)
        +None reset_password_via_recovery(payload, db)
    }

    class AuthTokenService {
        +str create_access_token(data, expires_delta, no_expiry)
    }

    AuthRouterInternal --> UserResponse
    AuthTokenService --> Token
Loading

File-Level Changes

Change Details Files
Stub the optional webauthn package in auth router tests so they run without the dependency installed and align fixtures with timezone-aware datetime usage.
  • Extend the _load_auth_router test helper to inject stub webauthn, webauthn.helpers, and webauthn.helpers.structs modules into sys.modules when the real package is absent, wiring minimal attribute placeholders expected by auth_router.
  • Keep the existing backend.database and backend.models monkeypatching but ensure it runs after the webauthn stubs are registered so imports succeed in a consistent environment.
  • Update password recovery–related test fixtures to create expires_at and reset_expires_at values with datetime.now(timezone.utc) instead of datetime.utcnow() to match the production code changes.
tests/test_auth_router_security.py
Make all auth and password-recovery time calculations timezone-aware to avoid deprecated utcnow usage and naive/aware comparison issues.
  • Replace all datetime.utcnow() calls in password recovery helpers, passkey registration/login flows, and related expiry checks with datetime.now(timezone.utc).
  • Ensure all expiry comparisons use timezone-aware now values to match how expiry timestamps are stored, preventing mixed naive/aware TypeErrors.
  • Update the access-token creation helper to compute JWT exp using datetime.now(timezone.utc), keeping token expiry consistent with the rest of the auth subsystem.
backend/auth_router.py
backend/auth.py
Align UserResponse Pydantic model configuration with Pydantic v2 conventions.
  • Remove the inner Config subclass on UserResponse and replace it with a model_config assignment using ConfigDict(from_attributes=True) so ORM instances can still be converted to response models under Pydantic v2.
backend/auth_router.py
Introduce a repository-level .gitignore tuned for Python artifacts.
  • Add a new .gitignore file configured to ignore standard Python build and cache outputs so bytecode caches like pycache/*.pyc are no longer tracked in git.
.gitignore

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Owner

@parkcheolhong parkcheolhong left a comment

Choose a reason for hiding this comment

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

수고했어요~

@parkcheolhong parkcheolhong marked this pull request as ready for review May 8, 2026 12:57
Copilot AI review requested due to automatic review settings May 8, 2026 12:57
@parkcheolhong parkcheolhong merged commit b0d3b71 into main May 8, 2026
5 checks passed
@parkcheolhong parkcheolhong deleted the copilot/fix-health-check-error-exposure branch May 8, 2026 12:57
@parkcheolhong
Copy link
Copy Markdown
Owner

정말 편리한 서비스 이런 것이 개발자들에게 꼭 필요한 것입니다.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In the WebAuthn stubs, consider making the stubbed functions/classes callable objects (e.g., simple no-op functions that raise a clear exception) rather than setting them to None, so that any unexpected use in tests fails with a more explicit and predictable error.
  • You repeat datetime.now(timezone.utc) many times across auth_router and tests; consider introducing a small helper (e.g., utcnow() or now_utc()) to centralize this behavior and make future changes to time handling easier.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the WebAuthn stubs, consider making the stubbed functions/classes callable objects (e.g., simple no-op functions that raise a clear exception) rather than setting them to None, so that any unexpected use in tests fails with a more explicit and predictable error.
- You repeat `datetime.now(timezone.utc)` many times across auth_router and tests; consider introducing a small helper (e.g., `utcnow()` or `now_utc()`) to centralize this behavior and make future changes to time handling easier.

## Individual Comments

### Comment 1
<location path="backend/auth_router.py" line_range="432" />
<code_context>
     user.passkey_device_label = str(state.get("device_label") or "이 기기 패스키")
     user.passkey_sign_count = int(verification.sign_count)
-    user.passkey_registered_at = datetime.utcnow()
+    user.passkey_registered_at = datetime.now(timezone.utc)
     db.add(user)
     db.commit()
</code_context>
<issue_to_address>
**issue (bug_risk):** Check that the ORM column type for `passkey_registered_at` is compatible with timezone-aware datetimes.

This field used to be set with a naive `datetime.utcnow()`, and is now using an aware `datetime.now(timezone.utc)`. If the column is declared as `DateTime(timezone=False)` or otherwise expects naive datetimes, some backends will strip the timezone or error. Please confirm the ORM column uses `timezone=True` (or equivalent) or that this field is consistently treated as timezone-aware across the codebase.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread backend/auth_router.py
user.passkey_device_label = str(state.get("device_label") or "이 기기 패스키")
user.passkey_sign_count = int(verification.sign_count)
user.passkey_registered_at = datetime.utcnow()
user.passkey_registered_at = datetime.now(timezone.utc)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Check that the ORM column type for passkey_registered_at is compatible with timezone-aware datetimes.

This field used to be set with a naive datetime.utcnow(), and is now using an aware datetime.now(timezone.utc). If the column is declared as DateTime(timezone=False) or otherwise expects naive datetimes, some backends will strip the timezone or error. Please confirm the ORM column uses timezone=True (or equivalent) or that this field is consistently treated as timezone-aware across the codebase.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to stabilize auth-related tests and runtime behavior by removing an optional webauthn import failure in tests, eliminating datetime.utcnow() deprecation warnings by switching to timezone-aware UTC datetimes, modernizing a Pydantic model config for v2, and adding a Python-focused .gitignore to prevent committing cache artifacts.

Changes:

  • Stub webauthn modules in tests/test_auth_router_security.py so backend.auth_router can be imported in test runs without the optional dependency installed.
  • Replace datetime.utcnow() usages with datetime.now(timezone.utc) in auth/token and auth router logic.
  • Update UserResponse to use Pydantic v2 ConfigDict(from_attributes=True) and add a standard .gitignore.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/test_auth_router_security.py Adds webauthn stubbing for import safety and updates fixtures to timezone-aware UTC datetimes.
backend/auth.py Makes JWT expiry generation timezone-aware (timezone.utc).
backend/auth_router.py Makes recovery/passkey expiry logic timezone-aware and updates Pydantic config to ConfigDict.
.gitignore Adds Python/venv/test/IDE/OS ignore rules to prevent cache artifacts from being committed.

Comment on lines +79 to +84
_stub_helpers = types.ModuleType("webauthn.helpers")
_stub_helpers.structs = _stub_structs

monkeypatch.setitem(sys.modules, "webauthn", _stub_webauthn)
monkeypatch.setitem(sys.modules, "webauthn.helpers", _stub_helpers)
monkeypatch.setitem(sys.modules, "webauthn.helpers.structs", _stub_structs)
parkcheolhong added a commit that referenced this pull request May 11, 2026
* Harden Pillow dependency floor to patched range for active image parsing CVEs (#7)

* chore: raise Pillow minimum version to 12.2

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* chore: remove accidental pycache artifacts

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8)

* chore: start codeql alert remediation plan

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* fix: remediate CodeQL security and quality findings

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* fix: finalize CodeQL remediation hardening updates

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* Sanitize health diagnostic errors to avoid exception detail exposure (#9)

* fix: redact health diagnostic exception details

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* test: make health sanitization checks portable

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* chore: remove compiled test artifacts

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* refactor: normalize diagnostic error codes

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* test: share diagnostic error code fixture

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* refactor: simplify safe diagnostic code map

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* Potential fix for code scanning alert no. 4: Information exposure through an exception (#10)

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): set explicit python-version in codeql workflow (#11)

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12)

* fix(tests): stub webauthn in auth_router test fixture to fix import failures

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* Add consolidated design-change report and expanded PR body draft (#13)

* docs: add overall design change and PR report

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* docs: make PR report paths portable

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

* docs: clarify bilingual PR report structure

Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d

Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants