Fix pre-existing bugs: PBKDF2 import, test function names, salt truncation
- Fix cryptography import: PBKDF2 -> PBKDF2HMAC - Fix test_security.py: use CredentialEncryption class instead of non-existent functions - Fix salt generation to include user_id in differentiation - Remove unavailable poplib3 dependency - All 53 tests pass Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> Agent-Logs-Url: https://github.com/christianlouis/pop_puller_to_gmail/sessions/de3ef930-a980-4958-8a9d-a2c802918e81
This commit is contained in:
@@ -8,7 +8,7 @@ from jose import JWTError, jwt
|
||||
from passlib.context import CryptContext
|
||||
from cryptography.fernet import Fernet
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2
|
||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||
import base64
|
||||
|
||||
from app.core.config import settings
|
||||
@@ -84,13 +84,13 @@ class CredentialEncryption:
|
||||
# Generate salt - in production, this should be unique per user
|
||||
if user_id is not None:
|
||||
# Per-user salt for production
|
||||
salt = f'pop3_forwarder_user_{user_id}'.encode('utf-8')[:16].ljust(16, b'0')
|
||||
salt = f'pop3fwd_usr_{user_id}'.encode('utf-8')[:16].ljust(16, b'\x00')
|
||||
else:
|
||||
# Default salt for system-wide operations (use with caution)
|
||||
salt = b'pop3_forwarder_0'
|
||||
|
||||
# Derive a proper Fernet key from the provided key
|
||||
kdf = PBKDF2(
|
||||
kdf = PBKDF2HMAC(
|
||||
algorithm=hashes.SHA256(),
|
||||
length=32,
|
||||
salt=salt,
|
||||
|
||||
@@ -56,6 +56,3 @@ faker==22.6.0
|
||||
python-dotenv==1.0.0
|
||||
schedule==1.2.0
|
||||
tenacity==8.2.3
|
||||
|
||||
# Legacy support (for migration)
|
||||
poplib3==0.0.4
|
||||
|
||||
@@ -6,8 +6,7 @@ from app.core.security import (
|
||||
get_password_hash,
|
||||
verify_password,
|
||||
create_access_token,
|
||||
encrypt_password,
|
||||
decrypt_password,
|
||||
CredentialEncryption,
|
||||
)
|
||||
|
||||
|
||||
@@ -60,7 +59,8 @@ class TestEncryption:
|
||||
password = "mailpassword123"
|
||||
user_id = 1
|
||||
|
||||
encrypted = encrypt_password(password, user_id)
|
||||
encryptor = CredentialEncryption(user_id=user_id)
|
||||
encrypted = encryptor.encrypt(password)
|
||||
|
||||
assert encrypted != password
|
||||
assert len(encrypted) > 50
|
||||
@@ -70,8 +70,9 @@ class TestEncryption:
|
||||
password = "mailpassword123"
|
||||
user_id = 1
|
||||
|
||||
encrypted = encrypt_password(password, user_id)
|
||||
decrypted = decrypt_password(encrypted, user_id)
|
||||
encryptor = CredentialEncryption(user_id=user_id)
|
||||
encrypted = encryptor.encrypt(password)
|
||||
decrypted = encryptor.decrypt(encrypted)
|
||||
|
||||
assert decrypted == password
|
||||
|
||||
@@ -81,15 +82,18 @@ class TestEncryption:
|
||||
user_id_1 = 1
|
||||
user_id_2 = 2
|
||||
|
||||
encrypted_1 = encrypt_password(password, user_id_1)
|
||||
encrypted_2 = encrypt_password(password, user_id_2)
|
||||
encryptor_1 = CredentialEncryption(user_id=user_id_1)
|
||||
encryptor_2 = CredentialEncryption(user_id=user_id_2)
|
||||
|
||||
encrypted_1 = encryptor_1.encrypt(password)
|
||||
encrypted_2 = encryptor_2.encrypt(password)
|
||||
|
||||
# Different users should produce different encrypted values
|
||||
assert encrypted_1 != encrypted_2
|
||||
|
||||
# But decryption should work correctly for each
|
||||
assert decrypt_password(encrypted_1, user_id_1) == password
|
||||
assert decrypt_password(encrypted_2, user_id_2) == password
|
||||
assert encryptor_1.decrypt(encrypted_1) == password
|
||||
assert encryptor_2.decrypt(encrypted_2) == password
|
||||
|
||||
def test_decrypt_with_wrong_user_id_fails(self):
|
||||
"""Test that decryption fails with wrong user ID"""
|
||||
@@ -97,7 +101,10 @@ class TestEncryption:
|
||||
user_id = 1
|
||||
wrong_user_id = 2
|
||||
|
||||
encrypted = encrypt_password(password, user_id)
|
||||
encryptor = CredentialEncryption(user_id=user_id)
|
||||
wrong_encryptor = CredentialEncryption(user_id=wrong_user_id)
|
||||
|
||||
encrypted = encryptor.encrypt(password)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
decrypt_password(encrypted, wrong_user_id)
|
||||
wrong_encryptor.decrypt(encrypted)
|
||||
|
||||
Reference in New Issue
Block a user