Skip to content

Commit

Permalink
WIP: Display a banner in the JI regarding the noble migration
Browse files Browse the repository at this point in the history
This is largely copied from the same functionality that was implemented
during the focal migration (ecfecea).

Co-authored-by: soleilera <[email protected]>
  • Loading branch information
legoktm and soleilera committed Nov 22, 2024
1 parent 037055d commit 81421e3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
8 changes: 8 additions & 0 deletions securedrop/journalist_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any, Optional, Tuple, Union

import i18n
import server_os
import template_filters
import version
from db import db
Expand Down Expand Up @@ -54,6 +55,11 @@ def create_app(config: SecureDropConfig) -> Flask:

app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SQLALCHEMY_DATABASE_URI"] = config.DATABASE_URI

# Check if the server OS is past EOL; if so, we'll display banners
app.config["OS_PAST_EOL"] = server_os.is_os_past_eol()
app.config["OS_NEEDS_MIGRATION_FIXES"] = server_os.needs_migration_fixes()

db.init_app(app)

class JSONEncoder(json.JSONEncoder):
Expand Down Expand Up @@ -109,6 +115,8 @@ def setup_g() -> Optional[Response]:
"""Store commonly used values in Flask's special g object"""

i18n.set_locale(config)
g.show_os_past_eol_warning = app.config["OS_PAST_EOL"]
g.show_os_needs_migration_fixes = app.config["OS_NEEDS_MIGRATION_FIXES"]

if InstanceConfig.get_default().organization_name:
g.organization_name = ( # pylint: disable=assigning-non-slot
Expand Down
9 changes: 9 additions & 0 deletions securedrop/journalist_templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
<body>

{% if session.logged_in() %}
{% if g.show_os_past_eol_warning %}
<div id="os-past-eol" class="alert-banner">
{{ gettext('<strong>Critical:</strong>&nbsp;&nbsp;The operating system used by your SecureDrop servers has reached its end-of-life. A manual update is required to re-enable the Source Interface and remain safe. Please contact your administrator. <a href="https://securedrop.org/focal-eol" rel="noreferrer">Learn More</a>') }}
</div>
{% elif g.show_os_needs_migration_fixes %}
<div id="os-near-eol" class="alert-banner">
{{ gettext('<strong>Important:</strong>&nbsp;&nbsp;Your SecureDrop server needs manual attention to resolve issues blocking automatic upgrade to the next operating system. Please contact your adminstrator. <a href="https://securedrop.org/focal-eol" rel="noreferrer">Learn More</a>') }}
</div>
{% endif %}
<nav aria-label="{{ gettext('Navigation') }}">
<a href="#main" class="visually-hidden until-focus">{{ gettext('Skip to main content') }}</a>
{{ gettext('Logged on as') }}
Expand Down
32 changes: 32 additions & 0 deletions securedrop/server_os.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import functools
import json
from datetime import date
from pathlib import Path

FOCAL_VERSION = "20.04"
NOBLE_VERSION = "24.04"

FOCAL_ENDOFLIFE = date(2025, 4, 2)


@functools.lru_cache
Expand All @@ -12,3 +18,29 @@ def get_os_release() -> str:
version_id = line.split("=")[1].strip().strip('"')
break
return version_id


def is_os_past_eol() -> bool:
"""
Check if it's focal and if today is past the official EOL date
"""
return get_os_release() == FOCAL_VERSION and date.today() >= FOCAL_ENDOFLIFE


def needs_migration_fixes() -> bool:
"""
See if the check script has flagged any issues
"""
if get_os_release() != FOCAL_VERSION:
return False
state_path = Path("/etc/securedrop-noble-migration.json")
if not state_path.exists():
# Script hasn't run yet
return False
contents = json.loads(state_path.read_text())
if "error" in contents:
# Something went wrong with the script itself,
# it needs manual fixes.
return True
# True if any of the checks failed
return not all(contents.values())
7 changes: 5 additions & 2 deletions securedrop/source_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Optional, Tuple

import i18n
import server_os
import template_filters
import version
import werkzeug
Expand Down Expand Up @@ -65,6 +66,8 @@ def setup_i18n() -> None:

# Check if the Submission Key is valid; if not, we'll disable the UI
app.config["SUBMISSION_KEY_VALID"] = validate_journalist_key()
# Check if the server OS is past EOL; if so, we'll disable the UI
app.config["OS_PAST_EOL"] = server_os.is_os_past_eol()

@app.errorhandler(CSRFError)
def handle_csrf_error(e: CSRFError) -> werkzeug.Response:
Expand Down Expand Up @@ -113,8 +116,8 @@ def check_tor2web() -> Optional[werkzeug.Response]:

@app.before_request
@ignore_static
def check_submission_key() -> Optional[werkzeug.Response]:
if not app.config["SUBMISSION_KEY_VALID"]:
def check_offline() -> Optional[werkzeug.Response]:
if not app.config["SUBMISSION_KEY_VALID"] or app.config["OS_PAST_EOL"]:
session.clear()
g.show_offline_message = True
return make_response(render_template("offline.html"), 503)
Expand Down

0 comments on commit 81421e3

Please sign in to comment.