diff --git a/securedrop/source_app/main.py b/securedrop/source_app/main.py index c1748c01668..a7644c56e39 100644 --- a/securedrop/source_app/main.py +++ b/securedrop/source_app/main.py @@ -296,8 +296,12 @@ def login(): @view.route('/logout') def logout(): + """ + If a user is logged in, show them a logout page that prompts them to + click the New Identity button in Tor Browser to complete their session. + Otherwise redirect to the main Source Interface page. + """ if logged_in(): - msg = render_template('logout_flashed_message.html') # Clear the session after we render the message so it's localized # If a user specified a locale, save it and restore it @@ -305,7 +309,8 @@ def logout(): session.clear() session['locale'] = user_locale - flash(Markup(msg), "important hide-if-not-tor-browser") - return redirect(url_for('.index')) + return render_template('logout.html') + else: + return redirect(url_for('.index')) return view diff --git a/securedrop/source_templates/logout.html b/securedrop/source_templates/logout.html new file mode 100644 index 00000000000..fea48777eb3 --- /dev/null +++ b/securedrop/source_templates/logout.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} +{% block body %} +

{{ gettext('One more thing....') }}

+

{{ gettext('Click the broom icon New Identity button in your Tor browser\'s toolbar. This will clear your Tor browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-black.png')) }}

+{% endblock %} diff --git a/securedrop/source_templates/logout_flashed_message.html b/securedrop/source_templates/logout_flashed_message.html deleted file mode 100644 index 3190d95486a..00000000000 --- a/securedrop/source_templates/logout_flashed_message.html +++ /dev/null @@ -1,6 +0,0 @@ -
- -
-
{{ gettext('Important!') }}
-

{{ gettext('Thank you for exiting your session! Please select "New Identity" from the onion button in the Tor browser\'s toolbar to clear all history of your SecureDrop usage from this device.') }}

-
diff --git a/securedrop/source_templates/session_timeout.html b/securedrop/source_templates/session_timeout.html index f3b1fcbac76..665c7822fc3 100644 --- a/securedrop/source_templates/session_timeout.html +++ b/securedrop/source_templates/session_timeout.html @@ -3,6 +3,7 @@
{{ gettext('Important!') }}
-

{{ gettext('Your session timed out due to inactivity. Please login again if you want to continue using SecureDrop, or select "New Identity" from the onion button in the Tor browser\'s toolbar to clear all history of your SecureDrop usage from this device. If you are not using Tor Browser, restart your browser.') }}

+ +

{{ gettext('You were logged out due to inactivity. Click the broom icon New Identity button in your Tor browser\'s toolbar. This will clear your Tor browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-black.png')) }}

diff --git a/securedrop/static/i/torbroom-black.png b/securedrop/static/i/torbroom-black.png new file mode 100644 index 00000000000..11281b3caf3 Binary files /dev/null and b/securedrop/static/i/torbroom-black.png differ diff --git a/securedrop/tests/functional/source_navigation_steps.py b/securedrop/tests/functional/source_navigation_steps.py index 3778c30dc0e..dd19437fd9a 100644 --- a/securedrop/tests/functional/source_navigation_steps.py +++ b/securedrop/tests/functional/source_navigation_steps.py @@ -19,6 +19,9 @@ def _is_on_lookup_page(self): def _is_on_generate_page(self): return self.wait_for(lambda: self.driver.find_element_by_id("create-form")) + def _is_on_logout_page(self): + return self.wait_for(lambda: self.driver.find_element_by_id("click-new-identity-tor")) + def _source_visits_source_homepage(self): self.driver.get(self.source_location) assert self._is_on_source_homepage() @@ -195,7 +198,7 @@ def reply_deleted(): def _source_logs_out(self): self.safe_click_by_id("logout") - self.wait_for(lambda: ("Submit for the first time" in self.driver.page_source)) + assert self._is_on_logout_page() def _source_not_found(self): self.driver.get(self.source_location + "/unlikely") @@ -218,7 +221,7 @@ def _source_sees_session_timeout_message(self): notification = self.driver.find_element_by_css_selector(".important") if not hasattr(self, "accept_languages"): - expected_text = "Your session timed out due to inactivity." + expected_text = "You were logged out due to inactivity." assert expected_text in notification.text def _source_sees_document_attachment_item(self): diff --git a/securedrop/tests/pageslayout/test_source.py b/securedrop/tests/pageslayout/test_source.py index 871c1822533..0f667642968 100644 --- a/securedrop/tests/pageslayout/test_source.py +++ b/securedrop/tests/pageslayout/test_source.py @@ -153,11 +153,11 @@ def test_index(self): self._source_visits_source_homepage() self._screenshot('source-index.png') - def test_logout_flashed_message(self): + def test_logout(self): self.disable_js_torbrowser_driver() self._source_visits_source_homepage() self._source_chooses_to_submit_documents() self._source_continues_to_submit_page() self._source_submits_a_file() self._source_logs_out() - self._screenshot('source-logout_flashed_message.png') + self._screenshot('source-logout_page.png') diff --git a/securedrop/tests/test_source.py b/securedrop/tests/test_source.py index 5c1310cf13d..14c5c516f00 100644 --- a/securedrop/tests/test_source.py +++ b/securedrop/tests/test_source.py @@ -251,7 +251,10 @@ def test_login_and_logout(source_app): assert 'logged_in' not in session assert 'codename' not in session text = resp.data.decode('utf-8') - assert 'Thank you for exiting your session!' in text + + # This is part of the logout page message instructing users + # to click the 'new identity' icon + assert 'This will clear your Tor browser activity data on this device' in text def test_user_must_log_in_for_protected_views(source_app): @@ -706,7 +709,7 @@ def test_source_session_expiration(config, source_app): assert not session text = resp.data.decode('utf-8') - assert 'Your session timed out due to inactivity' in text + assert 'You were logged out due to inactivity' in text def test_source_session_expiration_create(config, source_app): @@ -731,7 +734,7 @@ def test_source_session_expiration_create(config, source_app): assert not session text = resp.data.decode('utf-8') - assert 'Your session timed out due to inactivity' in text + assert 'You were logged out due to inactivity' in text def test_csrf_error_page(config, source_app): @@ -743,7 +746,7 @@ def test_csrf_error_page(config, source_app): resp = app.post(url_for('main.create'), follow_redirects=True) text = resp.data.decode('utf-8') - assert 'Your session timed out due to inactivity' in text + assert 'You were logged out due to inactivity' in text def test_source_can_only_delete_own_replies(source_app):