-
Notifications
You must be signed in to change notification settings - Fork 1
Add /auth/login endpoint for jwt securitzation #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add /auth/login endpoint for jwt securitzation #13
Conversation
- Test valid login returns 200 with correct JWT payload - Test wrong password returns 401 with 'Invalid credentials' - Test non-existent user returns 401 - Test missing data returns 400 with specific error message - Parametrize payload variations for missing data cases - Test PyJWT encoding error returns 500 with proper message
- Validate email and password from request - Look up user in MongoDB - Verify password hash with Flask-Bcrypt - Generate JWT with sub, iat, and exp claims - Handle PyJWTError with 500 response
There was a problem hiding this 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 implements JWT-based authentication by adding a /auth/login endpoint and a require_jwt decorator for protecting routes. The changes integrate Flask-Bcrypt for password hashing and PyJWT for token generation/validation, replacing the previous basic bcrypt implementation.
- Adds JWT authentication with login endpoint and route protection decorator
- Migrates from raw bcrypt to Flask-Bcrypt for consistent password hashing
- Updates database schema to use
passwordfield instead ofpassword_hash
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| app/extensions.py | Adds Flask-Bcrypt extension initialization |
| app/init.py | Initializes bcrypt extension in application factory |
| app/routes/auth_routes.py | Adds login endpoint with JWT token generation and migrates to Flask-Bcrypt |
| app/utils/decorators.py | Implements JWT validation decorator for protecting routes |
| scripts/seed_users.py | Updates user seeding to use new password field name |
| tests/conftest.py | Adds test fixtures for seeded user data with hashed passwords |
| tests/test_auth.py | Adds comprehensive tests for login endpoint functionality |
| tests/test_decorators.py | Adds thorough test coverage for JWT decorator validation |
| tests/scripts/test_seed_users.py | Updates test to use new password field name |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
tests/test_decorators.py
Outdated
| """ | ||
| Test suite for decorators | ||
| To test the decorator in isolation, we'll create a tiny, temporary Flask app inside out test file. |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: 'out' should be 'our'
| To test the decorator in isolation, we'll create a tiny, temporary Flask app inside out test file. | |
| To test the decorator in isolation, we'll create a tiny, temporary Flask app inside our test file. |
tests/test_auth.py
Outdated
| assert data["error"] == expected_message | ||
|
|
||
|
|
||
| def test_loginhandles_jwp_encoding_error(client, seeded_user_in_db): |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function name has typos: 'loginhandles' should be 'login_handles' and 'jwp' should be 'jwt'
| def test_loginhandles_jwp_encoding_error(client, seeded_user_in_db): | |
| def test_login_handles_jwt_encoding_error(client, seeded_user_in_db): |
tests/test_auth.py
Outdated
| } | ||
| # Patch jwt.encode() to be a mock | ||
| with patch("app.routes.auth_routes.jwt.encode") as mock_jwt_encode: | ||
| # Configure the mosk to raise the specific exception we want to test |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: 'mosk' should be 'mock'
| # Configure the mosk to raise the specific exception we want to test | |
| # Configure the mock to raise the specific exception we want to test |
tests/conftest.py
Outdated
| @pytest.fixture(scope="session") # because this data never changes | ||
| def mock_user_data(): | ||
| """Provides a dictionary of a test user's data, with a hashed password.""" | ||
| # USe Flask-Bcrypt's fucntion to CREATE the hash. |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment has typos: 'USe' should be 'Use' and 'fucntion' should be 'function'
| # USe Flask-Bcrypt's fucntion to CREATE the hash. | |
| # Use Flask-Bcrypt's function to CREATE the hash. |
app/utils/decorators.py
Outdated
| @@ -0,0 +1,65 @@ | |||
| # pylint: disable=too-many-return-statements | |||
| """...""" | |||
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module docstring is incomplete - should describe the purpose of the decorators module
| """...""" | |
| """ | |
| This module provides decorators for Flask routes, including JWT authentication. | |
| The `require_jwt` decorator protects routes by verifying JWT tokens in the | |
| 'Authorization: Bearer <token>' header, decoding and validating the token, | |
| and attaching the authenticated user to the request context. | |
| """ |
| import jwt | ||
| from email_validator import EmailNotValidError, validate_email | ||
| from flask import Blueprint, jsonify, request | ||
| from flask import Blueprint, current_app, jsonify, request |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Import organization: datetime and jwt imports should be grouped together as they are both third-party libraries
Description
This PR adds /auth/login endpoint (PyJWT) to issue tokens after password verification and integrates Flask-Bcrypt for password hashing/verification.
It also adds a require_jwt decorator that validates Authorization: Bearer , and attaches user.
Please delete options that are not relevant.
How Has This Been Tested?
Automated test suite in tests/test_auth.py
Manual Testing with cURL and mongosh
CI/CD
Checklist: