def test_decode_password_reset_token_ok_for_good_token( self, email_app, data_api_client, password_reset_token): with email_app.app_context(): token = generate_token(password_reset_token, "Key", 'PassSalt') assert decode_password_reset_token( token, data_api_client) == password_reset_token data_api_client.get_user.assert_called_once_with(123)
def test_decode_invitation_token_returns_an_error_and_role_if_token_expired( self, decode_time, expected_result, email_app): with freeze_time('2015-01-02 03:04:05'): data = { 'email_address': '*****@*****.**', 'supplier_id': 1234, 'supplier_name': 'A. Supplier', 'role': 'supplier' } token = generate_token( data, email_app.config['SHARED_EMAIL_KEY'], email_app.config.get('INVITE_EMAIL_TOKEN_NS') or email_app.config.get('INVITE_EMAIL_SALT'), ) with freeze_time(decode_time): with email_app.app_context(): if expected_result == 'ok': assert decode_invitation_token(token) == data else: assert decode_invitation_token(token) == { 'error': 'token_expired', 'role': 'supplier' }
def test_decode_password_reset_token_does_not_work_if_bad_token( self, email_app, data_api_client, password_reset_token): token = generate_token(password_reset_token, "Key", 'PassSalt')[1:] with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == { 'error': 'token_invalid' }
def test_cant_decode_token_with_wrong_key(self): token = generate_token({ 'key1': 'value1', 'key2': 'value2' }, secret_key='1234567890', namespace='1234567890') with pytest.raises(fernet.InvalidToken): decode_token(token, 'failed', '1234567890')
def test_decode_invitation_token_adds_the_role_key_to_old_style_buyer_tokens( email_app): data = {'email_address': '*****@*****.**'} token = generate_token(data, 'Key', 'Salt') with email_app.app_context(): assert decode_invitation_token(token) == { 'email_address': '*****@*****.**', 'role': 'buyer' }
def test_decode_invitation_token_adds_the_role_key_to_expired_old_style_buyer_tokens( self, email_app): with freeze_time('2015-01-02 03:04:05'): data = {'email_address': '*****@*****.**'} token = generate_token(data, 'Key', 'Salt') with email_app.app_context(): assert decode_invitation_token(token) == { 'error': 'token_expired', 'role': 'buyer' }
def test_decode_invitation_token_decodes_ok(self, email_app): with email_app.app_context(): # works with arbitrary fields data = { 'email_address': '*****@*****.**', 'supplier_id': 1234, 'foo': 'bar', 'role': 'supplier' } token = generate_token(data, 'Key', 'Salt') assert decode_invitation_token(token) == data
def test_decode_password_reset_token_does_not_work_if_token_expired( email_app, data_api_client, password_reset_token): with freeze_time('2015-01-02 03:04:05'): # Token was generated a year before current time token = generate_token(password_reset_token, 'Secret', 'PassSalt') with freeze_time('2016-01-02 03:04:05'): with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == { 'error': 'token_invalid' }
def test_decode_invitation_token_returns_an_error_if_token_invalid(email_app): with email_app.app_context(): data = { 'email_address': '*****@*****.**', 'supplier_id': 1234, 'supplier_name': 'A. Supplier', 'role': 'supplier' } token = generate_token(data, email_app.config['SHARED_EMAIL_KEY'], email_app.config['INVITE_EMAIL_SALT'])[1:] assert decode_invitation_token(token) == {'error': 'token_invalid'}
def test_decode_password_reset_token_does_not_work_if_password_changed_later_than_token( email_app, data_api_client, password_reset_token): with freeze_time('2016-01-01T11:00:00.30Z'): # Token was generated an hour earlier than password was changed token = generate_token(password_reset_token, 'Secret', 'PassSalt') with freeze_time('2016-01-01T13:00:00.30Z'): # Token is two hours old; password was changed an hour ago with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == { 'error': 'token_invalid' }
def test_decode_password_reset_token_user_inactive(self, email_app, data_api_client, password_reset_token): with freeze_time('2016-01-01T12:00:00.30Z'): token = generate_token(password_reset_token, "Key", 'PassSalt') data_api_client.get_user.return_value["users"]["active"] = False with freeze_time('2016-01-01T13:00:00.30Z'): with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == { 'error': 'user_inactive' }
def test_can_generate_and_decode_token(): with freeze_time('2016-01-01T12:00:00Z'): encrypted_token = generate_token({ 'key1': 'value1', 'key2': 'value2' }, secret_key='1234567890', namespace='0987654321') token, timestamp = decode_token(encrypted_token, '1234567890', '0987654321') assert token == {'key1': 'value1', 'key2': 'value2'} assert timestamp == datetime(2016, 1, 1, 12, 0, 0)
def test_generate_token_does_not_contain_plaintext_email( self, email_app, data_api_client, password_reset_token): with email_app.app_context(), freeze_time('2016-01-01T12:00:00.30Z'): token = generate_token(password_reset_token, 'Secret', 'PassSalt') # a fernet string always starts with the version, which should be 128 assert token[:4] == 'gAAA' token = token.encode('utf-8') # Personally identifiable information should not be readable without secret key assert b'*****@*****.**' not in base64.urlsafe_b64decode(token) # a fernet string contains the timestamp at which it was encrypted assert _parse_fernet_timestamp(token) == datetime(2016, 1, 1, 12)
def test_decode_password_reset_token_invalid_if_password_changed_since_token_was_generated( self, generation_time, expected_result, email_app, data_api_client, password_reset_token): with freeze_time(generation_time): token = generate_token(password_reset_token, "Key", 'PassSalt') with freeze_time('2016-01-01T13:00:00.30Z'): with email_app.app_context(): if expected_result == 'ok': assert decode_password_reset_token( token, data_api_client) == password_reset_token else: assert decode_password_reset_token(token, data_api_client) == { 'error': 'token_invalid' }
def test_decode_password_reset_token_is_only_valid_within_a_day_of_token_creation( self, decode_time, expected_result, email_app, data_api_client, password_reset_token): with email_app.app_context(): with freeze_time('2016-01-02 03:04:05'): token = generate_token(password_reset_token, "Key", 'PassSalt') with freeze_time(decode_time): if expected_result == 'ok': assert decode_password_reset_token( token, data_api_client) == password_reset_token else: assert decode_password_reset_token(token, data_api_client) == { 'error': 'token_invalid' }
def test_decode_invitation_token_returns_an_error_and_role_if_token_expired( email_app): with freeze_time('2015-01-02 03:04:05'): data = { 'email_address': '*****@*****.**', 'supplier_id': 1234, 'supplier_name': 'A. Supplier', 'role': 'supplier' } token = generate_token(data, email_app.config['SHARED_EMAIL_KEY'], email_app.config['INVITE_EMAIL_SALT']) with email_app.app_context(): assert decode_invitation_token(token) == { 'error': 'token_expired', 'role': 'supplier' }