2017-09-12 16:47:04 +00:00
|
|
|
"""Tests for the tools to communicate with the cloud."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
|
|
|
|
from botocore.exceptions import ClientError
|
|
|
|
import pytest
|
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
from homeassistant.components.cloud import auth_api
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def mock_cognito():
|
|
|
|
"""Mock warrant."""
|
|
|
|
with patch('homeassistant.components.cloud.auth_api._cognito') as mock_cog:
|
|
|
|
yield mock_cog()
|
|
|
|
|
|
|
|
|
|
|
|
def aws_error(code, message='Unknown', operation_name='fake_operation_name'):
|
|
|
|
"""Generate AWS error response."""
|
|
|
|
response = {
|
|
|
|
'Error': {
|
|
|
|
'Code': code,
|
|
|
|
'Message': message
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ClientError(response, operation_name)
|
|
|
|
|
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
def test_login_invalid_auth(mock_cognito):
|
2017-09-12 16:47:04 +00:00
|
|
|
"""Test trying to login with invalid credentials."""
|
2017-10-15 02:43:14 +00:00
|
|
|
cloud = MagicMock(is_logged_in=False)
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.authenticate.side_effect = aws_error('NotAuthorizedException')
|
2017-10-15 02:43:14 +00:00
|
|
|
|
2017-09-12 16:47:04 +00:00
|
|
|
with pytest.raises(auth_api.Unauthenticated):
|
2017-10-15 02:43:14 +00:00
|
|
|
auth_api.login(cloud, 'user', 'pass')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
assert len(cloud.write_user_info.mock_calls) == 0
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
def test_login_user_not_found(mock_cognito):
|
2017-09-12 16:47:04 +00:00
|
|
|
"""Test trying to login with invalid credentials."""
|
2017-10-15 02:43:14 +00:00
|
|
|
cloud = MagicMock(is_logged_in=False)
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.authenticate.side_effect = aws_error('UserNotFoundException')
|
2017-10-15 02:43:14 +00:00
|
|
|
|
2017-09-12 16:47:04 +00:00
|
|
|
with pytest.raises(auth_api.UserNotFound):
|
2017-10-15 02:43:14 +00:00
|
|
|
auth_api.login(cloud, 'user', 'pass')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
assert len(cloud.write_user_info.mock_calls) == 0
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
def test_login_user_not_confirmed(mock_cognito):
|
2017-09-12 16:47:04 +00:00
|
|
|
"""Test trying to login without confirming account."""
|
2017-10-15 02:43:14 +00:00
|
|
|
cloud = MagicMock(is_logged_in=False)
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.authenticate.side_effect = \
|
|
|
|
aws_error('UserNotConfirmedException')
|
2017-10-15 02:43:14 +00:00
|
|
|
|
2017-09-12 16:47:04 +00:00
|
|
|
with pytest.raises(auth_api.UserNotConfirmed):
|
2017-10-15 02:43:14 +00:00
|
|
|
auth_api.login(cloud, 'user', 'pass')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
assert len(cloud.write_user_info.mock_calls) == 0
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
def test_login(mock_cognito):
|
2017-09-12 16:47:04 +00:00
|
|
|
"""Test trying to login without confirming account."""
|
2017-10-15 02:43:14 +00:00
|
|
|
cloud = MagicMock(is_logged_in=False)
|
|
|
|
mock_cognito.id_token = 'test_id_token'
|
|
|
|
mock_cognito.access_token = 'test_access_token'
|
|
|
|
mock_cognito.refresh_token = 'test_refresh_token'
|
2017-09-12 16:47:04 +00:00
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
auth_api.login(cloud, 'user', 'pass')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
2017-10-15 02:43:14 +00:00
|
|
|
assert len(mock_cognito.authenticate.mock_calls) == 1
|
|
|
|
assert cloud.id_token == 'test_id_token'
|
|
|
|
assert cloud.access_token == 'test_access_token'
|
|
|
|
assert cloud.refresh_token == 'test_refresh_token'
|
|
|
|
assert len(cloud.write_user_info.mock_calls) == 1
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_register(mock_cognito):
|
|
|
|
"""Test registering an account."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
|
|
|
cloud = MagicMock()
|
|
|
|
auth_api.register(cloud, 'email@home-assistant.io', 'password')
|
2017-09-12 16:47:04 +00:00
|
|
|
assert len(mock_cognito.register.mock_calls) == 1
|
2017-10-15 02:43:14 +00:00
|
|
|
result_user, result_password = mock_cognito.register.mock_calls[0][1]
|
2018-01-03 18:16:59 +00:00
|
|
|
assert result_user == 'email@home-assistant.io'
|
2017-09-12 16:47:04 +00:00
|
|
|
assert result_password == 'password'
|
|
|
|
|
|
|
|
|
|
|
|
def test_register_fails(mock_cognito):
|
|
|
|
"""Test registering an account."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.register.side_effect = aws_error('SomeError')
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
2017-11-27 09:09:17 +00:00
|
|
|
auth_api.register(cloud, 'email@home-assistant.io', 'password')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_confirm_register(mock_cognito):
|
|
|
|
"""Test confirming a registration of an account."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
|
|
|
auth_api.confirm_register(cloud, '123456', 'email@home-assistant.io')
|
2017-09-12 16:47:04 +00:00
|
|
|
assert len(mock_cognito.confirm_sign_up.mock_calls) == 1
|
2017-10-15 02:43:14 +00:00
|
|
|
result_code, result_user = mock_cognito.confirm_sign_up.mock_calls[0][1]
|
2018-01-03 18:16:59 +00:00
|
|
|
assert result_user == 'email@home-assistant.io'
|
2017-09-12 16:47:04 +00:00
|
|
|
assert result_code == '123456'
|
|
|
|
|
|
|
|
|
|
|
|
def test_confirm_register_fails(mock_cognito):
|
|
|
|
"""Test an error during confirmation of an account."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.confirm_sign_up.side_effect = aws_error('SomeError')
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
2017-11-27 09:09:17 +00:00
|
|
|
auth_api.confirm_register(cloud, '123456', 'email@home-assistant.io')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
2017-12-29 13:46:10 +00:00
|
|
|
def test_resend_email_confirm(mock_cognito):
|
|
|
|
"""Test starting forgot password flow."""
|
|
|
|
cloud = MagicMock()
|
|
|
|
auth_api.resend_email_confirm(cloud, 'email@home-assistant.io')
|
|
|
|
assert len(mock_cognito.client.resend_confirmation_code.mock_calls) == 1
|
|
|
|
|
|
|
|
|
|
|
|
def test_resend_email_confirm_fails(mock_cognito):
|
|
|
|
"""Test failure when starting forgot password flow."""
|
|
|
|
cloud = MagicMock()
|
|
|
|
mock_cognito.client.resend_confirmation_code.side_effect = \
|
|
|
|
aws_error('SomeError')
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
|
|
|
auth_api.resend_email_confirm(cloud, 'email@home-assistant.io')
|
|
|
|
|
|
|
|
|
2017-09-12 16:47:04 +00:00
|
|
|
def test_forgot_password(mock_cognito):
|
|
|
|
"""Test starting forgot password flow."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
|
|
|
auth_api.forgot_password(cloud, 'email@home-assistant.io')
|
2017-09-12 16:47:04 +00:00
|
|
|
assert len(mock_cognito.initiate_forgot_password.mock_calls) == 1
|
|
|
|
|
|
|
|
|
|
|
|
def test_forgot_password_fails(mock_cognito):
|
|
|
|
"""Test failure when starting forgot password flow."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.initiate_forgot_password.side_effect = aws_error('SomeError')
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
2017-11-27 09:09:17 +00:00
|
|
|
auth_api.forgot_password(cloud, 'email@home-assistant.io')
|
2017-09-12 16:47:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_confirm_forgot_password(mock_cognito):
|
|
|
|
"""Test confirming forgot password."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
2017-09-12 16:47:04 +00:00
|
|
|
auth_api.confirm_forgot_password(
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud, '123456', 'email@home-assistant.io', 'new password')
|
2017-09-12 16:47:04 +00:00
|
|
|
assert len(mock_cognito.confirm_forgot_password.mock_calls) == 1
|
|
|
|
result_code, result_password = \
|
|
|
|
mock_cognito.confirm_forgot_password.mock_calls[0][1]
|
|
|
|
assert result_code == '123456'
|
|
|
|
assert result_password == 'new password'
|
|
|
|
|
|
|
|
|
|
|
|
def test_confirm_forgot_password_fails(mock_cognito):
|
|
|
|
"""Test failure when confirming forgot password."""
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud = MagicMock()
|
2017-09-12 16:47:04 +00:00
|
|
|
mock_cognito.confirm_forgot_password.side_effect = aws_error('SomeError')
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
|
|
|
auth_api.confirm_forgot_password(
|
2017-11-27 09:09:17 +00:00
|
|
|
cloud, '123456', 'email@home-assistant.io', 'new password')
|
2017-10-15 02:43:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_check_token_writes_new_token_on_refresh(mock_cognito):
|
|
|
|
"""Test check_token writes new token if refreshed."""
|
|
|
|
cloud = MagicMock()
|
|
|
|
mock_cognito.check_token.return_value = True
|
|
|
|
mock_cognito.id_token = 'new id token'
|
|
|
|
mock_cognito.access_token = 'new access token'
|
|
|
|
|
|
|
|
auth_api.check_token(cloud)
|
|
|
|
|
|
|
|
assert len(mock_cognito.check_token.mock_calls) == 1
|
|
|
|
assert cloud.id_token == 'new id token'
|
|
|
|
assert cloud.access_token == 'new access token'
|
|
|
|
assert len(cloud.write_user_info.mock_calls) == 1
|
|
|
|
|
|
|
|
|
|
|
|
def test_check_token_does_not_write_existing_token(mock_cognito):
|
|
|
|
"""Test check_token won't write new token if still valid."""
|
|
|
|
cloud = MagicMock()
|
|
|
|
mock_cognito.check_token.return_value = False
|
|
|
|
|
|
|
|
auth_api.check_token(cloud)
|
|
|
|
|
|
|
|
assert len(mock_cognito.check_token.mock_calls) == 1
|
|
|
|
assert cloud.id_token != mock_cognito.id_token
|
|
|
|
assert cloud.access_token != mock_cognito.access_token
|
|
|
|
assert len(cloud.write_user_info.mock_calls) == 0
|
|
|
|
|
|
|
|
|
|
|
|
def test_check_token_raises(mock_cognito):
|
|
|
|
"""Test we raise correct error."""
|
|
|
|
cloud = MagicMock()
|
|
|
|
mock_cognito.check_token.side_effect = aws_error('SomeError')
|
|
|
|
|
|
|
|
with pytest.raises(auth_api.CloudError):
|
|
|
|
auth_api.check_token(cloud)
|
|
|
|
|
|
|
|
assert len(mock_cognito.check_token.mock_calls) == 1
|
|
|
|
assert cloud.id_token != mock_cognito.id_token
|
|
|
|
assert cloud.access_token != mock_cognito.access_token
|
|
|
|
assert len(cloud.write_user_info.mock_calls) == 0
|