75 lines
3.5 KiB
Python
75 lines
3.5 KiB
Python
"""Existing staff credentials remain usable across password storage formats."""
|
|
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
from logistics_chat import create_app, db
|
|
|
|
|
|
class StaffLoginTests(unittest.TestCase):
|
|
def setUp(self):
|
|
directory = tempfile.TemporaryDirectory()
|
|
self.addCleanup(directory.cleanup)
|
|
root = Path(directory.name)
|
|
self.app = create_app({'TESTING': True, 'DATABASE': root / 'history.db',
|
|
'UPLOAD_DIR': root / 'uploads', 'BACKUP_DIR': root / 'backups',
|
|
'LOG_DIR': root / 'logs', 'DEEPSEEK_API_KEY': '',
|
|
'CUSTOMER_DEMO_ENABLED': False})
|
|
self.client = self.app.test_client()
|
|
|
|
def add_staff(self, password):
|
|
with self.app.app_context():
|
|
connection = db.connect()
|
|
connection.execute('INSERT INTO agents(username,password,name) VALUES(?,?,?)',
|
|
('staff-fixture', password, '测试客服'))
|
|
connection.commit()
|
|
|
|
def login(self, password):
|
|
return self.client.post('/admin/login', json={'username': 'staff-fixture', 'password': password})
|
|
|
|
def test_existing_hashed_password_accepts_original_password(self):
|
|
password = 'Fixture-密码-42!'
|
|
for method in ('pbkdf2:sha256:1000', 'scrypt:1024:8:1'):
|
|
with self.subTest(method=method):
|
|
encoded = generate_password_hash(password, method=method)
|
|
with self.app.app_context():
|
|
connection = db.connect()
|
|
connection.execute('DELETE FROM agents')
|
|
connection.commit()
|
|
self.add_staff(encoded)
|
|
response = self.login(password)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.json, {'ok': True, 'name': '测试客服'})
|
|
with self.app.app_context():
|
|
connection = db.connect()
|
|
self.assertEqual(connection.execute('SELECT password FROM agents').fetchone()[0], encoded)
|
|
|
|
def test_wrong_password_and_stored_hash_cannot_log_in(self):
|
|
encoded = generate_password_hash('Fixture-password', method='pbkdf2:sha256:1000')
|
|
self.add_staff(encoded)
|
|
self.assertEqual(self.login('wrong-password').status_code, 401)
|
|
self.assertEqual(self.login(encoded).status_code, 401)
|
|
|
|
def test_legacy_plain_password_still_works(self):
|
|
self.add_staff('旧密码-fixture')
|
|
self.assertEqual(self.login('旧密码-fixture').status_code, 200)
|
|
self.assertEqual(self.login('wrong').status_code, 401)
|
|
|
|
def test_invalid_credentials_are_rejected_without_server_errors(self):
|
|
self.add_staff('legacy-fixture')
|
|
for payload in ({}, [], 'invalid', {'username': [], 'password': {}},
|
|
{'username': 'staff-fixture', 'password': ''},
|
|
{'username': 'missing', 'password': 'legacy-fixture'}):
|
|
with self.subTest(payload=payload):
|
|
self.app.extensions['staff_login_attempts'].clear()
|
|
self.assertEqual(self.client.post('/admin/login', json=payload).status_code, 401)
|
|
|
|
def test_corrupt_hash_cannot_be_used_as_a_plain_password(self):
|
|
encoded = 'pbkdf2:invalid$fixture$invalid'
|
|
self.add_staff(encoded)
|
|
self.assertEqual(self.login(encoded).status_code, 401)
|
|
self.assertEqual(self.login('test-password').status_code, 401)
|