From bad6b0409bdc5586734bcba65dd0bcbdf3c55f41 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Thu, 22 Apr 2021 19:33:29 +0530 Subject: [PATCH] Removes all EOL related code and tests --- securedrop/journalist_app/__init__.py | 8 --- securedrop/server_os.py | 26 +-------- securedrop/source_app/__init__.py | 12 ---- securedrop/tests/test_journalist.py | 59 -------------------- securedrop/tests/test_source.py | 80 --------------------------- 5 files changed, 1 insertion(+), 184 deletions(-) diff --git a/securedrop/journalist_app/__init__.py b/securedrop/journalist_app/__init__.py index 920e56a356..88994fe43c 100644 --- a/securedrop/journalist_app/__init__.py +++ b/securedrop/journalist_app/__init__.py @@ -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 @@ -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, @@ -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 diff --git a/securedrop/server_os.py b/securedrop/server_os.py index 0bac8fa743..a9107ba6c2 100644 --- a/securedrop/server_os.py +++ b/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 diff --git a/securedrop/source_app/__init__.py b/securedrop/source_app/__init__.py index 37297e2392..f2781e5d5a 100644 --- a/securedrop/source_app/__init__.py +++ b/securedrop/source_app/__init__.py @@ -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: @@ -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 diff --git a/securedrop/tests/test_journalist.py b/securedrop/tests/test_journalist.py index b5ff436653..70b49d79c9 100644 --- a/securedrop/tests/test_journalist.py +++ b/securedrop/tests/test_journalist.py @@ -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(): diff --git a/securedrop/tests/test_source.py b/securedrop/tests/test_source.py index 2cab8abd13..04cdd36421 100644 --- a/securedrop/tests/test_source.py +++ b/securedrop/tests/test_source.py @@ -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")