Skip to content

Commit

Permalink
app, test: skip round trip to user endpoint during login (fix #575)
Browse files Browse the repository at this point in the history
  • Loading branch information
redshiftzero committed Nov 6, 2019
1 parent c4f3f37 commit d50a4ea
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 84 deletions.
1 change: 1 addition & 0 deletions securedrop_client/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
ENCODING = 'utf-8'
LOGLEVEL = os.environ.get('LOGLEVEL', 'info').upper()


def init(sdc_home: str) -> None:
safe_mkdir(sdc_home)
safe_mkdir(sdc_home, 'data')
Expand Down
26 changes: 8 additions & 18 deletions securedrop_client/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,17 @@ def on_authenticate_success(self, result):
"""
logger.info('{} successfully logged in'.format(self.api.username))
self.gui.hide_login()
self.sync_api()
self.call_api(self.api.get_current_user,
self.on_get_current_user_success,
self.on_get_current_user_failure)
user = storage.update_and_get_user(
self.api.token_journalist_uuid,
self.api.username,
self.api.journalist_first_name,
self.api.journalist_last_name,
self.session)
self.gui.show_main_window(user)
self.api_job_queue.login(self.api)

self.is_authenticated = True
self.resume_queues()
self.sync_api()

def on_authenticate_failure(self, result: Exception) -> None:
# Failed to authenticate. Reset state with failure message.
Expand All @@ -334,19 +337,6 @@ def on_authenticate_failure(self, result: Exception) -> None:
'Please verify your credentials and try again.')
self.gui.show_login_error(error=error)

def on_get_current_user_success(self, result) -> None:
user = storage.update_and_get_user(
result['uuid'],
result['username'],
result['first_name'],
result['last_name'],
self.session)
self.gui.show_main_window(user)

def on_get_current_user_failure(self, result: Exception) -> None:
self.api = None
self.gui.show_login_error(error=_('Could not find your account.'))

def login_offline_mode(self):
"""
Allow user to view in offline mode without authentication.
Expand Down
2 changes: 2 additions & 0 deletions tests/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def User(**attrs):
defaults = dict(
uuid='user-uuid-{}'.format(USER_COUNT),
username='test-user-id-{}'.format(USER_COUNT),
firstname='slim',
lastname='shady'
)

defaults.update(attrs)
Expand Down
76 changes: 10 additions & 66 deletions tests/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,92 +182,36 @@ def test_Controller_on_authenticate_failure(homedir, config, mocker, session_mak
'verify your credentials and try again.')


def test_Controller_on_authenticate_success(homedir, config, mocker, session_maker):
def test_Controller_on_authenticate_success(homedir, config, mocker, session_maker,
session):
"""
Ensure the client syncs when the user successfully logs in.
Using the `config` fixture to ensure the config is written to disk.
"""
user = factory.User()
mock_gui = mocker.MagicMock()
mock_api_job_queue = mocker.patch("securedrop_client.logic.ApiJobQueue")
co = Controller('http://localhost', mock_gui, session_maker, homedir)
co.sync_api = mocker.MagicMock()
co.session.add(user)
co.session.commit()
co.api = mocker.MagicMock()
co.call_api = mocker.MagicMock()
co.api.token_journalist_uuid = user.uuid
co.api.username = user.username
co.api.journalist_first_name = user.firstname
co.api.journalist_last_name = user.lastname
co.resume_queues = mocker.MagicMock()
login = mocker.patch.object(co.api_job_queue, 'login')
current_user_api_result = {
'uuid': 'mock_uuid',
'username': 'mock_username',
'first_name': 'mock_firstname',
'last_name': 'mock_lastname'}
co.api.get_current_user = mocker.MagicMock(return_value=(current_user_api_result))

co.on_authenticate_success(True)

co.sync_api.assert_called_once_with()
assert co.is_authenticated
assert mock_api_job_queue.called
login.assert_called_with(co.api)
co.resume_queues.assert_called_once_with()


def test_Controller_on_get_current_user_success(mocker, session_maker, session, homedir):
co = Controller('http://localhost', mocker.MagicMock(), session_maker, homedir)
co.api = mocker.MagicMock()
co.call_api = mocker.MagicMock()
user = factory.User(uuid='mock_uuid', username='mock_username')
session.add(user)
session.commit()
current_user_api_result = {
'uuid': 'mock_uuid',
'username': 'mock_username',
'first_name': 'firstname_mock',
'last_name': 'lastname_mock'}

co.on_get_current_user_success(current_user_api_result)

user = session.query(db.User).filter_by(uuid='mock_uuid').one_or_none()
assert user.firstname == 'firstname_mock'
assert user.lastname == 'lastname_mock'
assert user.fullname == 'firstname_mock lastname_mock'
assert user.initials == 'fl'
co.gui.show_main_window.assert_called_with(user)


def test_Controller_on_get_current_user_success_no_name(mocker, session_maker, session, homedir):
co = Controller('http://localhost', mocker.MagicMock(), session_maker, homedir)
co.api = mocker.MagicMock()
co.call_api = mocker.MagicMock()
user = factory.User(uuid='mock_uuid', username='mock_username')
session.add(user)
session.commit()
storage = mocker.patch('securedrop_client.logic.storage')
storage.update_and_get_user = mocker.MagicMock(return_value=user)
current_user_api_result = {
'uuid': 'mock_uuid',
'username': 'mock_username',
'first_name': None,
'last_name': None}

co.on_get_current_user_success(current_user_api_result)

user = session.query(db.User).filter_by(uuid='mock_uuid').one_or_none()
assert user.firstname is None
assert user.lastname is None
assert user.fullname == 'mock_username'
assert user.initials == 'mo'
co.gui.show_main_window.assert_called_with(user)


def test_Controller_on_get_current_user_failure(homedir, mocker, session_maker):
co = Controller('http://localhost', mocker.MagicMock(), session_maker, homedir)
result = Exception('oh no')

co.on_get_current_user_failure(result)

co.gui.show_login_error.assert_called_once_with(error='Could not find your account.')
assert co.api is None


def test_Controller_completed_api_call_without_current_object(
homedir,
config,
Expand Down

0 comments on commit d50a4ea

Please sign in to comment.