Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add v2 onion service deprecation warning #5366

Merged
merged 1 commit into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions securedrop/journalist_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ def create_app(config: 'SDConfig') -> Flask:
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db.init_app(app)

v2_enabled = path.exists(path.join(config.SECUREDROP_DATA_ROOT, 'source_v2_url'))
v3_enabled = path.exists(path.join(config.SECUREDROP_DATA_ROOT, 'source_v3_url'))
app.config.update(V2_ONION_ENABLED=v2_enabled, V3_ONION_ENABLED=v3_enabled)

app.storage = Storage(config.STORE_DIR,
config.TEMP_DIR,
config.JOURNALIST_KEY)
Expand Down Expand Up @@ -169,6 +173,9 @@ def setup_g() -> 'Optional[Response]':
g.html_lang = i18n.locale_to_rfc_5646(g.locale)
g.locales = i18n.get_locale2name()

if not app.config['V3_ONION_ENABLED'] or app.config['V2_ONION_ENABLED']:
g.show_v2_onion_eol_warning = True

if request.path.split('/')[1] == 'api':
pass # We use the @token_required decorator for the API endpoints
else: # We are not using the API
Expand Down
6 changes: 6 additions & 0 deletions securedrop/journalist_templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
<body>

{% if g.user %}
{% if g.show_v2_onion_eol_warning %}
<div id="v2-onion-eol" class="warning-banner">
{{ gettext('<strong>Update Required:</strong> Your SecureDrop servers are still running v2 Onion Services, which are being phased out for security reasons. In February 2021, v2 Onion Services will be disabled, and your SecureDrop servers may become unreachable. <a href="//securedrop.org/v2-onion-eol" rel="noreferrer">Learn More</a>') }}
</div>
{% endif %}

<div id="logout">
{{ gettext('Logged on as') }} <a href="{{ url_for('account.edit') }}" id="link-edit-account">{{ g.user.username }}</a> |
{% if g.user and g.user.is_admin %}
Expand Down
3 changes: 3 additions & 0 deletions securedrop/sass/_base.sass
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
@import modules/panel
// Warning - Messages to user e.g. about protecting your security by turning Tor settings to high
@import modules/warning
// Warning - Warning messages that show up in a banner to the user.
@import modules/warning-banner
// Confirm prompt - When deleting something this prompt is shown
@import modules/confirm-prompt
// 'Serious' text - Seems to be unused. Delete?
Expand Down Expand Up @@ -119,6 +121,7 @@
+cols
+panel
+warning
+warning-banner
+confirm-prompt
+serious-text
+code
Expand Down
17 changes: 17 additions & 0 deletions securedrop/sass/modules/_warning-banner.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
=warning-banner
.warning-banner
display: block
background-color: $color_warning_purple
color: white
padding: 10px 0
width: 100%
text-align: center
font-size: small
box-sizing: border-box
-moz-box-sizing: border-box

a
color: white

.close
cursor: pointer
60 changes: 60 additions & 0 deletions securedrop/tests/test_journalist.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,66 @@ def _login_user(app, username, password, otp_secret):
assert hasattr(g, 'user') # ensure logged in


def test_user_sees_v2_eol_warning_if_only_v2_is_enabled(config, journalist_app, test_journo):
journalist_app.config.update(V2_ONION_ENABLED=True, V3_ONION_ENABLED=False)
with journalist_app.test_client() as app:
_login_user(
app,
test_journo['username'],
test_journo['password'],
test_journo['otp_secret'])

resp = app.get(url_for('main.index'))

text = resp.data.decode('utf-8')
assert "v2-onion-eol" in text, text


def test_user_sees_v2_eol_warning_if_both_v2_and_v3_enabled(config, journalist_app, test_journo):
journalist_app.config.update(V2_ONION_ENABLED=True, V3_ONION_ENABLED=True)
with journalist_app.test_client() as app:
_login_user(
app,
test_journo['username'],
test_journo['password'],
test_journo['otp_secret'])

resp = app.get(url_for('main.index'))

text = resp.data.decode('utf-8')
assert "v2-onion-eol" in text, text


def test_user_does_not_see_v2_eol_warning_if_only_v3_enabled(config, journalist_app, test_journo):
journalist_app.config.update(V2_ONION_ENABLED=False, V3_ONION_ENABLED=True)
with journalist_app.test_client() as app:
_login_user(
app,
test_journo['username'],
test_journo['password'],
test_journo['otp_secret'])

resp = app.get(url_for('main.index'))

text = resp.data.decode('utf-8')
assert "v2-onion-eol" not in text, text


def test_user_sees_v2_eol_warning_if_both_urls_do_not_exist(config, journalist_app, test_journo):
journalist_app.config.update(V2_ONION_ENABLED=False, V3_ONION_ENABLED=False)
with journalist_app.test_client() as app:
_login_user(
app,
test_journo['username'],
test_journo['password'],
test_journo['otp_secret'])

resp = app.get(url_for('main.index'))

text = resp.data.decode('utf-8')
assert "v2-onion-eol" in text, text


def test_user_with_whitespace_in_username_can_login(journalist_app):
# Create a user with whitespace at the end of the username
with journalist_app.app_context():
Expand Down