Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions auth/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,9 @@ def decorated_function(*args, **kwargs):
g.user_id = user_id
g.user = user_data
return f(*args, **kwargs)
except Exception as e:
return jsonify({'error': 'Unauthorized', 'details': str(e)}), 401
except Exception:
# Do not leak exception details to the client
return jsonify({'error': 'Unauthorized'}), 401
return decorated_function


Expand Down
Empty file added src/handoff/__init__.py
Empty file.
51 changes: 51 additions & 0 deletions tests/test_auth_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import unittest
from unittest.mock import MagicMock, patch
import sys

# Mock cache_db module before importing auth.utils
cache_db_mock = MagicMock()
sys.modules['cache_db'] = cache_db_mock
sys.modules['cache_db.redis_client'] = cache_db_mock.redis_client
sys.modules['cache_db.models'] = cache_db_mock.models

from flask import Flask
from auth.utils import login_required, PasswordUtils, JWTUtils


class TestAuthUtils(unittest.TestCase):
def setUp(self):
self.app = Flask(__name__)
self.app.config['TESTING'] = True

def test_login_required_does_not_leak_exception_details(self):
@self.app.route('/protected')
@login_required
def protected_route():
return "success"

with patch('auth.utils.verify_jwt_in_request', side_effect=RuntimeError("Internal database connection error - secret_db_uri")):
client = self.app.test_client()
response = client.get('/protected')

self.assertEqual(response.status_code, 401)
data = response.get_json()
self.assertEqual(data, {'error': 'Unauthorized'})
# Verify details or stack trace are not in response payload
self.assertNotIn('details', data)
self.assertNotIn('secret_db_uri', str(data))

def test_password_utils_hash_and_verify(self):
hashed = PasswordUtils.hash_password("supersecret123")
self.assertTrue(PasswordUtils.verify_password("supersecret123", hashed))
self.assertFalse(PasswordUtils.verify_password("wrongpassword", hashed))

def test_jwt_utils_create_and_decode(self):
access_token, refresh_token = JWTUtils.create_tokens("user123", "testuser")
decoded = JWTUtils.decode_token(access_token)
self.assertIsNotNone(decoded)
self.assertEqual(decoded['user_id'], "user123")
self.assertEqual(decoded['username'], "testuser")


if __name__ == '__main__':
unittest.main()