From bc91227a8bd97c1924b8b8c64eeb249d1eaa0d8f Mon Sep 17 00:00:00 2001 From: ro Date: Wed, 5 Feb 2020 09:46:41 -0500 Subject: [PATCH] - Add logout page and route that directs users to click the New Identity button in Tor browser to complete their session, if they were logged in, else redirectst to main source interface page. - Remove logout_flashed message since we redirect to a new page now. - Update functional tests to include _is_on_logout_page method and replace test_logout_flashed_message with test_logout screenshot in testsourcelayout --- securedrop/source_app/main.py | 11 ++++++++--- securedrop/source_templates/logout.html | 6 ++++++ .../source_templates/logout_flashed_message.html | 6 ------ securedrop/source_templates/session_timeout.html | 2 +- securedrop/static/i/torbroom-black.png | Bin 0 -> 1894 bytes .../tests/functional/source_navigation_steps.py | 7 +++++-- securedrop/tests/pageslayout/test_source.py | 4 ++-- securedrop/tests/test_source.py | 11 +++++++---- 8 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 securedrop/source_templates/logout.html delete mode 100644 securedrop/source_templates/logout_flashed_message.html create mode 100644 securedrop/static/i/torbroom-black.png 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..b6b566d4306 --- /dev/null +++ b/securedrop/source_templates/logout.html @@ -0,0 +1,6 @@ +{% 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..cf39dabc2bd 100644 --- a/securedrop/source_templates/session_timeout.html +++ b/securedrop/source_templates/session_timeout.html @@ -3,6 +3,6 @@
{{ 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 0000000000000000000000000000000000000000..11281b3caf36574323624145f6ac26ccc7394f41 GIT binary patch literal 1894 zcmV-s2buVZP)kj1qOuyazC{yMJe^(YutmUk1@D~N@ zV2NzK*c#=l5(ya!EoVJ6_ z#ox2Cu-b{1v*Av&xFacH4rF=gLdKJUy~wo4qy0KauD58GNow(~rjT zU-aqNNe7+ULrO7rIyeJ3=Rjs3G(Hr=EhQVTgdeUmQ^85b>tP@>Z(9uc>1YgT1C6Bq zd9ARrHq^4YNfdkHFSm%Zy2)c_h5VKkmH1G{WoIw#ON zjO`}{7N@eulfJLrjRBcLUu!F5-|Bq+bNb610e^sQfjGKx8X7Y$SXXHUo_-_@zl+Y5>c=pUK30 zk<}2g*u_XOq&bAFn9W59c>WS&`o2iL8QZR7Uq-Gx>^7|HV89qmL;n?U2xCm*x~Brh zSvV#Dzca(gY@Hv#mKxd{u#yeD1ZT_jB#M3pYGxGD4O#}Z4lHu+lf-4dBQxfzb&Cs7 zpz{TfJ|}x5OMu6Nbe2MQ0W8((HafTjdmqAl=|r}^;P*z_SAvac@Vk+^o^FxvsZ^3N zJ`erPV1BXlAehfL$rqd_9ktL6@FEq(wkzt0d=i|L*_PE3{4+<@L#C<|(U;wg%*=9w zN$x%f3vp&!pEHf~VG8wnr=uNe`8ki5+0YB_Mh_;a{$4o{N51x1k0-$g&uu)mo$SR) zQMKaI`iH z%!W6V4O-M!=3end?}!>G6Z~pr?-K_xz#@WsQQy+L5Qe@dM!p?=fvM-2G7(@ zdoik~o54w1r{!ZuhrNG!c{N_-&%G8HkR&AdJ02(7LQd4!<&Y05AH$ICk&l9pidQL( zWNljoDHP8Hg7()IA`O6FJvK1=+zX@c<1JnyJ0!L4v4g}d6a&u(mfsfDkKb)1Sj8wPR(_^%;N zQ{NP>3+1W%BCTjZ=5eD;wCj$ux}KbYHc)5IWoqHI9)aev>7jz3Rw-A!?+TxY0&WBI zGuz&tu0A&@o52r*Qwm=ReBaO@GVvW1xQec#ThR|y^XrYz=zeffF(be{4(6H4#o!CU zw}YPn%NJmg4~{Pfk10(>^q0Xg$r5u(LbjZo10LTGCHScwdObYu_9Rv`5ih|`{+lK? zu}zLxe?oV1tb?jJ{@U^+xXe#Nz6s&kb;?BS0N(mq4_)KLb4?q#&VKAf@Uzv%{kZAs zxv0e)YgfrbzS=gxN$8H4|a;|p&v7vj>tT}b5Yg8rNB_T3xOxN zf+y;DhyDa+EWXMsQA**wYu12&1&0cCjcuuvWw-I8CjR2?;rQMhK<%U9N}h#tb3?in z?81a}Ot=ayg7G%+AK*|Nu3@Xer-74*6Cpnv>HxZMI$QwO<1z9O4J*|gZqm92TyHH8m#EwlK=n!07*qoM6N<$f(6fqLI3~& literal 0 HcmV?d00001 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..fa6c4b1b566 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' 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):