Skip to content

Conversation

@amaziahub
Copy link
Contributor

@amaziahub amaziahub commented Apr 16, 2025

Summary by CodeRabbit

  • New Features
    • Added token-based authentication to entry creation and retrieval endpoints, requiring users to provide a valid access token.
  • Tests
    • Updated test drivers and clients to support and propagate authentication tokens when making API requests.

@amaziahub amaziahub changed the title Validate token api feat: Validate token api Apr 18, 2025
@rockem
Copy link

rockem commented Apr 20, 2025

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Apr 20, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Apr 20, 2025

Warning

Rate limit exceeded

@amaziahub has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 45 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between dc08816 and 75565f6.

📒 Files selected for processing (3)
  • service/entries/router.py (1 hunks)
  • tests/support/app_driver.py (3 hunks)
  • tests/support/client.py (2 hunks)

Walkthrough

This update introduces token-based authentication to both the service endpoints and the test infrastructure. The service router now requires a bearer token for POST and GET entry endpoints, using a new dependency to extract and verify the token. Correspondingly, the test support classes are updated to handle authentication: the test driver logs in to obtain a token, and the client methods for creating and retrieving entries are modified to include the token in the Authorization header. These changes ensure that all entry-related API interactions are authenticated.

Changes

File(s) Change Summary
service/entries/router.py Added token extraction and verification to POST and GET endpoints; introduced extract_token function; updated endpoint signatures to require token.
tests/support/app_driver.py Added token instance variable; updated startup to log in and store token; modified entry methods to pass token to client.
tests/support/client.py Updated create_entry and get_entries to accept optional token and include Authorization header; added _build_auth_header static method; reformatted some requests calls.

Poem

In the warren of code, a new guard appears,
With tokens in paw, it allays our fears.
Now entries are safe, both written and read,
For only the trusted may hop ahead.
Our tests now log in, with secrets to share—
A rabbit’s delight: security everywhere!
🐇🔐


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc08816 and 6992542.

📒 Files selected for processing (3)
  • service/entries/router.py (1 hunks)
  • tests/support/app_driver.py (3 hunks)
  • tests/support/client.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/support/app_driver.py (3)
tests/support/client.py (3)
  • login (72-78)
  • create_entry (38-43)
  • get_entries (45-49)
service/login/router.py (1)
  • login (26-30)
service/entries/router.py (2)
  • create_entry (22-29)
  • get_entries (33-37)
tests/support/client.py (5)
tests/support/app_driver.py (3)
  • is_healthy (34-35)
  • create_entry (37-38)
  • get_entries (40-41)
service/login/token.py (1)
  • verify (47-55)
service/entries/router.py (2)
  • create_entry (22-29)
  • get_entries (33-37)
service/entries/model/entry.py (2)
  • Entry (6-15)
  • from_json (11-12)
service/entries/persistence/entries_store.py (1)
  • get_entries (32-34)
🪛 Ruff (0.8.2)
service/entries/router.py

17-17: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


17-17: Do not perform function call HTTPBearer in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (9)
tests/support/client.py (3)

38-43: LGTM: Authentication support for create_entry

The addition of the token parameter and authorization header to the create_entry method correctly implements the authentication requirements for this endpoint.


45-49: LGTM: Authentication support for get_entries

The addition of the token parameter and authorization header to the get_entries method correctly implements the authentication requirements for this endpoint.


21-21: LGTM: Token parameter in constructor

Adding an optional token parameter to the constructor provides flexibility in how the client is initialized and used, supporting both authenticated and unauthenticated scenarios.

tests/support/app_driver.py (3)

12-12: LGTM: Token instance variable

Adding a token instance variable with initial value of None is a good practice for storing the authentication token after login.


37-38: LGTM: Token usage in create_entry

The method now correctly passes the token to the client's create_entry method, enabling authenticated requests.


40-41: LGTM: Token usage in get_entries

The method now correctly passes the token to the client's get_entries method, enabling authenticated requests.

service/entries/router.py (3)

22-29: LGTM: Token verification in create_entry endpoint

The create_entry endpoint now correctly extracts and verifies the access token before processing the request. The updated use of model_dump() instead of dict() also follows modern Pydantic practices.


32-37: LGTM: Token verification in get_entries endpoint

The get_entries endpoint now correctly extracts and verifies the access token before returning entries, ensuring proper authentication.


4-6: LGTM: Security imports

The added imports for FastAPI security components and the token module are necessary and appropriate for implementing token-based authentication.

Also applies to: 10-10

Copy link

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6992542 and ba2cabc.

📒 Files selected for processing (1)
  • service/entries/router.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
service/entries/router.py

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (6)
service/entries/router.py (6)

4-6: Appropriate imports added for authentication

These imports correctly bring in the necessary FastAPI security components needed for token-based authentication.


10-10: Token module import added correctly

The token module import is appropriately placed to support the new authentication functionality.


15-16: Good implementation of module-level security scheme

The bearer_scheme variable follows the recommended FastAPI pattern and addresses the static analysis warning about function calls in parameter defaults that was flagged in previous reviews.


18-19: Well-designed token extraction function

This helper function cleanly extracts the token from the credentials object. The implementation is concise and follows FastAPI best practices.

🧰 Tools
🪛 Ruff (0.8.2)

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


24-25: Authentication dependency correctly added to endpoint

The token extraction is properly integrated as a dependency for the create_entry endpoint.


34-37: Authentication consistently applied across endpoints

Authentication has been correctly implemented for the GET endpoint, maintaining consistency across the API. The token verification occurs before accessing the data, which is the proper security sequence.

However, consider adding logging here as well for consistency with the POST endpoint:

def get_entries(
        access_token: str = Depends(extract_token)
):
+   logger.debug(f"Verifying access token for get_entries request")
    token.verify(access_token)
+   logger.debug(f"Token verification successful")
    return persistence.get_entries()

Comment on lines 27 to 29
logger.info(f"Received entry data: {entry.model_dump()}")
token.verify(access_token)
entry = persistence.add_entry(entry.model_dump())
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify potential error handling for token verification

While the token verification and model_dump() usage are appropriate, consider adding error handling or logging around the token verification process to aid in troubleshooting authentication failures.

Consider expanding with:

    logger.info(f"Received entry data: {entry.model_dump()}")
+   logger.debug(f"Verifying access token")
    token.verify(access_token)
+   logger.debug(f"Token verification successful")
    entry = persistence.add_entry(entry.model_dump())

Run this to check if the token module already has sufficient error handling:


🏁 Script executed:

#!/bin/bash
# Check if the token.verify method has error handling
cat ../login/token.py | grep -A 10 "def verify"

Length of output: 99


🏁 Script executed:

#!/bin/bash
# Locate any token.py files in the repository
echo "Searching for token.py files:"
find . -type f -name "token.py"

# Grep all Python files for verify method definitions
echo -e "\nSearching for 'def verify' in Python files:"
grep -R -n "def verify" --include '*.py' .

Length of output: 326


🏁 Script executed:

#!/bin/bash
# Display the implementation of token.verify to assess error handling
grep -R -n "def verify" -A 20 service/login/token.py

Length of output: 320


Enhance logging around token verification

The token.verify method already catches JWT errors (expired or invalid tokens) and raises appropriate exceptions. To improve traceability during authentication failures, add debug‑level logs immediately before and after verification:

     logger.info(f"Received entry data: {entry.model_dump()}")
+    logger.debug("Verifying access token")
     token.verify(access_token)
+    logger.debug("Token verification successful")
     entry = persistence.add_entry(entry.model_dump())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
logger.info(f"Received entry data: {entry.model_dump()}")
token.verify(access_token)
entry = persistence.add_entry(entry.model_dump())
logger.info(f"Received entry data: {entry.model_dump()}")
logger.debug("Verifying access token")
token.verify(access_token)
logger.debug("Token verification successful")
entry = persistence.add_entry(entry.model_dump())

@amaziahub
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Apr 21, 2025

✅ Actions performed

Full review triggered.

Copy link

@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

♻️ Duplicate comments (1)
service/entries/router.py (1)

22-28: Implement previously suggested debug logging around token verification

The token verification is correctly implemented, but the previously suggested debug logging isn't included. Adding these logs would improve traceability during authentication failures.

+    logger.debug("Verifying access token")
     token.verify(access_token)
+    logger.debug("Token verification successful")
     entry = persistence.add_entry(entry.model_dump())
🧹 Nitpick comments (1)
service/entries/router.py (1)

32-37: Consider making get_entries async for consistency

The create_entry endpoint is async but get_entries is not. Consider making both endpoints async for consistency in the codebase.

-def get_entries(
+async def get_entries(
     access_token: str = Depends(extract_token)
 ):
     token.verify(access_token)
     return persistence.get_entries()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c24415d and 9f074cd.

📒 Files selected for processing (1)
  • service/entries/router.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
service/entries/router.py (4)
service/entries/model/entry.py (2)
  • Entry (6-15)
  • to_json (14-15)
service/entries/persistence/entries_store.py (3)
  • EntriesStore (7-38)
  • add_entry (24-30)
  • get_entries (32-34)
tests/support/client.py (3)
  • login (74-80)
  • create_entry (38-43)
  • get_entries (45-49)
service/login/token.py (1)
  • verify (47-55)
🪛 Ruff (0.8.2)
service/entries/router.py

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (4)
service/entries/router.py (4)

15-19: Well-implemented token extraction dependency

The implementation follows FastAPI best practices by:

  1. Creating a module-level security scheme variable
  2. Using a dedicated dependency function to extract tokens

This addresses the previous B008 lint warning by avoiding function calls in parameter defaults.

🧰 Tools
🪛 Ruff (0.8.2)

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


24-25: Proper authentication integration with the entry creation endpoint

The implementation correctly requires authentication by adding the access_token dependency parameter.


28-28: Good use of model_dump() instead of dict()

Using model_dump() follows the recommended Pydantic approach for serializing models and matches the to_json() implementation in the Entry model.


33-36: Properly secured get_entries endpoint

The implementation correctly requires and verifies authentication tokens before returning entries.

Copy link

@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: 2

♻️ Duplicate comments (1)
tests/support/app_driver.py (1)

28-28: ⚠️ Potential issue

Hardcoded secret used for authentication

The secret "Creeper" is hardcoded in the source code, which is a security risk. Secrets should be managed through environment variables or secure configuration management.

Apply this change to improve security:

- self.token = self.login("Creeper")["access_token"]
+ test_secret = os.getenv("TEST_SECRET", "Creeper")  # Fallback for local testing only
+ self.token = self.login(test_secret)["access_token"]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc08816 and 9f074cd.

📒 Files selected for processing (3)
  • service/entries/router.py (1 hunks)
  • tests/support/app_driver.py (3 hunks)
  • tests/support/client.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/support/client.py (5)
tests/support/app_driver.py (3)
  • is_healthy (34-35)
  • create_entry (37-38)
  • get_entries (40-41)
service/login/token.py (1)
  • verify (47-55)
service/entries/router.py (2)
  • create_entry (23-29)
  • get_entries (33-37)
service/entries/model/entry.py (2)
  • Entry (6-15)
  • from_json (11-12)
service/entries/persistence/entries_store.py (1)
  • get_entries (32-34)
tests/support/app_driver.py (4)
service/login/router.py (1)
  • login (26-30)
tests/support/client.py (3)
  • login (74-80)
  • create_entry (38-43)
  • get_entries (45-49)
service/entries/router.py (2)
  • create_entry (23-29)
  • get_entries (33-37)
service/entries/persistence/entries_store.py (1)
  • get_entries (32-34)
🪛 Ruff (0.8.2)
service/entries/router.py

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (9)
tests/support/client.py (3)

51-57: Good implementation of the auth header builder

The implementation correctly handles the case when no token is provided by checking if the token exists before adding it to the headers. This prevents sending invalid Bearer None headers.


38-41: API authentication properly implemented

The method now correctly passes authentication headers when a token is provided. This aligns with the authentication changes in the endpoints.


45-47: API authentication properly implemented for GET method

The implementation correctly includes the token in the authorization header when fetching entries, matching the authentication requirements in the service layer.

tests/support/app_driver.py (2)

37-38: Token properly passed to client methods

The method now correctly forwards the authentication token to the client, ensuring that test requests are properly authenticated.


40-41: Token properly passed to get_entries

The method now correctly forwards the authentication token to the client, ensuring that test requests are properly authenticated.

service/entries/router.py (4)

15-15: Good module-level security scheme

Creating a module-level variable for the security scheme follows best practices and addresses the B008 issue from static analysis.


18-19: Well-implemented token extraction

The extract_token function is a clean implementation to extract credentials from the authorization header.

🧰 Tools
🪛 Ruff (0.8.2)

18-18: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


23-29: Token verification added to entry creation

The endpoint now properly verifies the token before processing the request. Also noticed a change from dictionary conversion to using the Pydantic model_dump() method, which is the recommended approach.

Consider adding logging around token verification for better troubleshooting:

+    logger.debug("Verifying access token")
     token.verify(access_token)
+    logger.debug("Token verification successful")

33-37: Token verification added to get entries endpoint

The endpoint now properly requires and verifies an authentication token before returning entries, which improves security.

Consider adding logging here as well:

+    logger.debug("Verifying access token for get_entries")
     token.verify(access_token)
+    logger.debug("Token verification successful")

@amaziahub
Copy link
Contributor Author

amaziahub commented Apr 21, 2025

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Apr 21, 2025

✅ Actions performed

Full review triggered.

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