Skip to content

Commit

Permalink
Merge pull request #5169 from freedomofpress/gui-updater-error-handling
Browse files Browse the repository at this point in the history
Improve admin workstation updater GUI error handling
  • Loading branch information
redshiftzero authored Mar 31, 2020
2 parents 97470c4 + 118db3c commit 3770689
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
11 changes: 7 additions & 4 deletions journalist_gui/journalist_gui/SecureDropUpdater.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,29 @@ def run(self):
tailsconfig_command = ("/home/amnesia/Persistent/"
"securedrop/securedrop-admin "
"tailsconfig")
self.failure_reason = ""
try:
child = pexpect.spawn(tailsconfig_command)
child.expect('SUDO password:')
self.output += child.before.decode('utf-8')
child.sendline(self.sudo_password)
child.expect(pexpect.EOF)
child.expect(pexpect.EOF, timeout=120)
self.output += child.before.decode('utf-8')
child.close()

# For Tailsconfig to be considered a success, we expect no
# failures in the Ansible output.
if child.exitstatus:
self.update_success = False
self.failure_reason = strings.tailsconfig_failed_generic_reason # noqa
if "[sudo via ansible" in self.output:
self.failure_reason = strings.tailsconfig_failed_sudo_password
else:
self.failure_reason = strings.tailsconfig_failed_generic_reason
else:
self.update_success = True
except pexpect.exceptions.TIMEOUT:
self.update_success = False
self.failure_reason = strings.tailsconfig_failed_sudo_password

self.failure_reason = strings.tailsconfig_failed_timeout
except subprocess.CalledProcessError:
self.update_success = False
self.failure_reason = strings.tailsconfig_failed_generic_reason
Expand Down
7 changes: 5 additions & 2 deletions journalist_gui/journalist_gui/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@
"Contact your SecureDrop administrator "
"or [email protected] immediately.")
tailsconfig_failed_sudo_password = ('Administrator password incorrect. '
'Exiting upgrade - '
'click Update Now to try again.')
'Click Update Now to try again.')
tailsconfig_failed_generic_reason = ("Tails workstation configuration failed. "
"Contact your administrator. "
"If you are an administrator, contact "
"[email protected].")
tailsconfig_failed_timeout = ("Tails workstation configuration took too long. "
"Contact your administrator. "
"If you are an administrator, contact "
"[email protected].")
install_update_button = 'Update Now'
install_later_button = 'Update Later'
sudo_password_text = ("Enter the Tails Administrator password you "
Expand Down
14 changes: 13 additions & 1 deletion journalist_gui/test_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ def test_tailsconfigThread_generic_failure(self, pt):

@mock.patch('pexpect.spawn')
def test_tailsconfigThread_sudo_password_is_wrong(self, pt):
child = pt()
before = MagicMock()
before.decode.return_value = "stuff[sudo via ansible, key=blahblahblah"
child.before = before
self.window.tails_thread.run()
self.assertNotIn("failed=0", self.window.output)
self.assertEqual(self.window.update_success, False)
self.assertEqual(self.window.failure_reason,
strings.tailsconfig_failed_sudo_password)

@mock.patch('pexpect.spawn')
def test_tailsconfigThread_timeout(self, pt):
child = pt()
before = MagicMock()
before.decode.side_effect = ["some data",
Expand All @@ -213,7 +225,7 @@ def test_tailsconfigThread_sudo_password_is_wrong(self, pt):
self.assertNotIn("failed=0", self.window.output)
self.assertEqual(self.window.update_success, False)
self.assertEqual(self.window.failure_reason,
strings.tailsconfig_failed_sudo_password)
strings.tailsconfig_failed_timeout)

@mock.patch('pexpect.spawn')
def test_tailsconfigThread_some_other_subprocess_error(self, pt):
Expand Down

0 comments on commit 3770689

Please sign in to comment.