204 lines
No EOL
8.5 KiB
Python
204 lines
No EOL
8.5 KiB
Python
import os
|
|
import unittest
|
|
import unittest.mock
|
|
import json
|
|
from .context import create_app, default_test_config
|
|
from backend.data import db
|
|
from backend.data import dao_reset_password_tokens
|
|
from backend.data import dao_users
|
|
from backend.data.data_models import RegisteringUser
|
|
|
|
class ResetPasswordUnitTest(unittest.TestCase):
|
|
|
|
url_path = '/reset/password'
|
|
app = create_app(default_test_config)
|
|
client = app.test_client()
|
|
|
|
def setUp(self):
|
|
with self.app.app_context():
|
|
db.init_db()
|
|
|
|
def tearDown(self):
|
|
with self.app.app_context():
|
|
db.close_db()
|
|
os.remove("testdb")
|
|
|
|
def save_token(self, token, username, expires_at):
|
|
with self.app.app_context():
|
|
dao_reset_password_tokens.insert_token(token=token,username=username,expires_at=expires_at)
|
|
|
|
def insert_user(self, user: RegisteringUser):
|
|
with self.app.app_context():
|
|
user_id = dao_users.insert_user(user)
|
|
return user_id
|
|
|
|
def test_without_username_error_is_shown(self):
|
|
expected = {'message':'Username cannot be empty!','code':410}
|
|
|
|
response = self.client.post(self.url_path)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
def test_without_password_error_is_shown(self):
|
|
expected = {'message':'Password cannot be empty!','code':420}
|
|
|
|
data = {'username': 'myname'}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
def test_without_reset_password_token_error_is_shown(self):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
|
|
data = {'username': 'myname', 'password': 'mypass'}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
def test_without_valid_reset_password_token_error_is_shown(self):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
|
|
data = {'username': 'myname', 'password': 'mypass', 'reset_password_token': 'alma'}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
def test_without_saved_reset_password_token_error_is_shown(self):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
|
|
data = {'username': 'myname', 'password': 'mypass', 'reset_password_token': 'alma'}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_with_expired_reset_password_token_error_is_shown(self, mock_time):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
token = 'alma'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 10)
|
|
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_with_valid_registration_token_but_no_user_error_is_shown(self, mock_time):
|
|
expected = {'message': 'User cannot be found!','code':412}
|
|
token = 'alma'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 1100)
|
|
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_with_valid_token_and_user_success_is_shown(self, mock_time):
|
|
expected = {'message': 'Password was Saved!','code':201}
|
|
token = 'alma'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 1100)
|
|
user = RegisteringUser(
|
|
name = username,
|
|
password = 'citrom',
|
|
otp_secret = 'base32secret3232'
|
|
)
|
|
user_id = self.insert_user(user)
|
|
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(200, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_reset_password_can_be_used(self, mock_time):
|
|
expected_keys = {'otp_secret'}
|
|
expected_format = r'^otpauth://totp/FnivesVOD:myname\?secret=[^&]*&issuer=FnivesVOD$'
|
|
token = 'alma'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 1100)
|
|
user = RegisteringUser(
|
|
name = username,
|
|
password = 'citrom',
|
|
otp_secret = 'base32secret3232'
|
|
)
|
|
self.insert_user(user)
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
self.client.post(self.url_path, data=data)
|
|
|
|
login_data = {'username': username, 'password': 'mypass'}
|
|
response = self.client.post('/login', data=login_data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(200, response.status_code)
|
|
self.assertEqual(expected_keys, set(actual_response_json.keys()))
|
|
self.assertRegex(actual_response_json['otp_secret'], expected_format)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_same_token_cannot_be_reused(self, mock_time):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
token = 'alma'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 1100)
|
|
user = RegisteringUser(
|
|
name = username,
|
|
password = 'citrom',
|
|
otp_secret = 'base32secret3232'
|
|
)
|
|
self.insert_user(user)
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
self.client.post(self.url_path, data=data)
|
|
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
@unittest.mock.patch('time.time', return_value=1000)
|
|
def test_no_previous_token_can_be_reused_after_reset(self, mock_time):
|
|
expected = {'message': 'Invalid Reset Password Token given!','code':461}
|
|
token = 'alma'
|
|
token2 = 'alma2'
|
|
username = 'myname'
|
|
self.save_token(token = token, username = username, expires_at = 1100)
|
|
self.save_token(token = token2, username = username, expires_at = 1100)
|
|
user = RegisteringUser(
|
|
name = username,
|
|
password = 'citrom',
|
|
otp_secret = 'base32secret3232'
|
|
)
|
|
self.insert_user(user)
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token}
|
|
self.client.post(self.url_path, data=data)
|
|
|
|
data = {'username': username, 'password': 'mypass', 'reset_password_token': token2}
|
|
response = self.client.post(self.url_path, data=data)
|
|
actual_response_json = json.loads(response.data.decode())
|
|
|
|
self.assertEqual(400, response.status_code)
|
|
self.assertEqual(expected, actual_response_json)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main(verbosity=2) |