Skip to content

Commit

Permalink
Removes all EOL related code and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kushaldas committed Apr 22, 2021
1 parent 8fa6d12 commit bad6b04
Show file tree
Hide file tree
Showing 5 changed files with 1 addition and 184 deletions.
8 changes: 0 additions & 8 deletions securedrop/journalist_app/__init__.py
Expand Up @@ -23,7 +23,6 @@
JournalistInterfaceSessionInterface,
cleanup_expired_revoked_tokens)
from models import InstanceConfig, Journalist
from server_os import is_os_near_eol, is_os_past_eol
from store import Storage

import typing
Expand Down Expand Up @@ -72,8 +71,6 @@ def create_app(config: 'SDConfig') -> Flask:
app.config['SQLALCHEMY_DATABASE_URI'] = config.DATABASE_URI
db.init_app(app)

app.config.update(OS_PAST_EOL=is_os_past_eol(), OS_NEAR_EOL=is_os_near_eol())

# TODO: Attaching a Storage dynamically like this disables all type checking (and
# breaks code analysis tools) for code that uses current_app.storage; it should be refactored
app.storage = Storage(config.STORE_DIR,
Expand Down Expand Up @@ -179,11 +176,6 @@ def setup_g() -> 'Optional[Response]':
except FileNotFoundError:
app.logger.error("Site logo not found.")

if app.config["OS_PAST_EOL"]:
g.show_os_past_eol_warning = True
elif app.config["OS_NEAR_EOL"]:
g.show_os_near_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
26 changes: 1 addition & 25 deletions securedrop/server_os.py
@@ -1,38 +1,14 @@
import functools
import subprocess
from datetime import date

FOCAL_VERSION = "20.04"


@functools.lru_cache()
def get_xenial_eol_date() -> date:
return date(2021, 4, 30)


@functools.lru_cache()
def get_os_release() -> str:
return subprocess.run(
["lsb_release", "--release", "--short"],
["/usr/bin/lsb_release", "--release", "--short"],
check=True,
stdout=subprocess.PIPE,
universal_newlines=True
).stdout.strip()


def is_os_past_eol() -> bool:
"""
Assumption: Any OS that is not Focal is an earlier version of the OS.
"""
if get_os_release() != FOCAL_VERSION and date.today() > get_xenial_eol_date():
return True
return False


def is_os_near_eol() -> bool:
"""
Assumption: Any OS that is not Focal is an earlier version of the OS.
"""
if get_os_release() != FOCAL_VERSION and date.today() <= get_xenial_eol_date():
return True
return False
12 changes: 0 additions & 12 deletions securedrop/source_app/__init__.py
Expand Up @@ -26,7 +26,6 @@
from source_app.decorators import ignore_static
from source_app.utils import logged_in, was_in_generate_flow
from store import Storage
from server_os import is_os_past_eol


def get_logo_url(app: Flask) -> str:
Expand Down Expand Up @@ -60,17 +59,6 @@ def setup_i18n() -> None:
"""Store i18n-related values in Flask's special g object"""
i18n.set_locale(config)

app.config.update(OS_PAST_EOL=is_os_past_eol())

@app.before_request
@ignore_static
def disable_ui() -> Optional[str]:
if app.config["OS_PAST_EOL"]:
session.clear()
g.show_offline_message = True
return render_template("base.html")
return None

# The default CSRF token expiration is 1 hour. Since large uploads can
# take longer than an hour over Tor, we increase the valid window to 24h.
app.config['WTF_CSRF_TIME_LIMIT'] = 60 * 60 * 24
Expand Down
59 changes: 0 additions & 59 deletions securedrop/tests/test_journalist.py
Expand Up @@ -62,65 +62,6 @@ def _login_user(app, username, password, otp_secret):
assert hasattr(g, 'user') # ensure logged in


def test_user_sees_os_warning_if_server_past_eol(config, journalist_app, test_journo):
journalist_app.config.update(OS_PAST_EOL=True, OS_NEAR_EOL=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 'id="os-past-eol"' in text, text
assert 'id="os-near-eol"' not in text, text


def test_user_sees_os_warning_if_server_past_eol_sanity_check(config, journalist_app, test_journo):
"""
Sanity check (both conditions cannot be True but test guard against developer error)
"""
journalist_app.config.update(OS_PAST_EOL=True, OS_NEAR_EOL=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 'id="os-past-eol"' in text, text
assert 'id="os-near-eol"' not in text, text


def test_user_sees_os_warning_if_server_close_to_eol(config, journalist_app, test_journo):
journalist_app.config.update(OS_PAST_EOL=False, OS_NEAR_EOL=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 'id="os-past-eol"' not in text, text
assert 'id="os-near-eol"' in text, text


def test_user_does_not_see_os_warning_if_server_is_current(config, journalist_app, test_journo):
journalist_app.config.update(OS_PAST_EOL=False, OS_NEAR_EOL=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 'id="os-past-eol"' not in text, text
assert 'id="os-near-eol"' not 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
80 changes: 0 additions & 80 deletions securedrop/tests/test_source.py
Expand Up @@ -38,86 +38,6 @@
overly_long_codename = 'a' * (PassphraseGenerator.MAX_PASSPHRASE_LENGTH + 1)


def test_source_interface_is_disabled_when_xenial_is_eol(config, source_app):
disabled_endpoints = [
"main.index",
"main.generate",
"main.login",
"info.download_public_key",
"info.tor2web_warning",
"info.recommend_tor_browser",
"info.why_download_public_key",
]
static_assets = [
"css/source.css",
"i/custom_logo.png",
"i/font-awesome/fa-globe-black.png",
"i/favicon.png",
]
with patch("server_os.get_os_release", return_value="16.04"):
with patch("server_os.get_xenial_eol_date", return_value=date(2020, 1, 1)):
app = source_app_module.create_app(config)
with app.test_client() as test_client:
for endpoint in disabled_endpoints:
resp = test_client.get(url_for(endpoint))
assert resp.status_code == 200
text = resp.data.decode("utf-8")
assert "We're sorry, our SecureDrop is currently offline." in text
# Ensure static assets are properly served
for asset in static_assets:
resp = test_client.get(url_for("static", filename=asset))
assert resp.status_code == 200
text = resp.data.decode("utf-8")
assert "We're sorry, our SecureDrop is currently offline." not in text


def test_source_interface_is_not_disabled_before_xenial_eol(config, source_app):
disabled_endpoints = [
"main.index",
"main.generate",
"main.login",
"info.download_public_key",
"info.tor2web_warning",
"info.recommend_tor_browser",
"info.why_download_public_key",
]
with patch("server_os.get_os_release", return_value="16.04"):
with patch("server_os.get_xenial_eol_date", return_value=date(2200, 1, 1)):
app = source_app_module.create_app(config)
with app.test_client() as test_client:
print(
"OS_RELEASE: {} EOL DATE: {}".format(
server_os.get_os_release(), server_os.get_xenial_eol_date()
)
)
for endpoint in disabled_endpoints:
resp = test_client.get(url_for(endpoint), follow_redirects=True)
assert resp.status_code == 200
text = resp.data.decode("utf-8")
assert "We're sorry, our SecureDrop is currently offline." not in text


def test_source_interface_is_not_disabled_for_focal(config, source_app):
disabled_endpoints = [
"main.index",
"main.generate",
"main.login",
"info.download_public_key",
"info.tor2web_warning",
"info.recommend_tor_browser",
"info.why_download_public_key",
]
with patch("server_os.get_os_release", return_value="20.04"):
with patch("server_os.get_xenial_eol_date", return_value=date(2020, 1, 1)):
app = source_app_module.create_app(config)
with app.test_client() as test_client:
for endpoint in disabled_endpoints:
resp = test_client.get(url_for(endpoint))
assert resp.status_code == 200
text = resp.data.decode("utf-8")
assert "We're sorry, our SecureDrop is currently offline." not in text


def test_logo_default_available(source_app):
# if the custom image is available, this test will fail
custom_image_location = os.path.join(config.SECUREDROP_ROOT, "static/i/custom_logo.png")
Expand Down

0 comments on commit bad6b04

Please sign in to comment.