mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 04:20:17 +02:00
563 lines
19 KiB
Python
563 lines
19 KiB
Python
"""
|
|
Django system checks for Alliance Auth
|
|
"""
|
|
|
|
from typing import List
|
|
from django import db
|
|
from django.core.checks import CheckMessage, Error, register, Warning
|
|
from allianceauth.utils.cache import get_redis_client
|
|
from django.utils import timezone
|
|
from packaging.version import InvalidVersion, Version as Pep440Version
|
|
from celery import current_app
|
|
from django.conf import settings
|
|
from sqlite3.dbapi2 import sqlite_version_info
|
|
|
|
"""
|
|
A = System Packages
|
|
B = Configuration
|
|
"""
|
|
|
|
|
|
@register()
|
|
def django_settings(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that Django settings are correctly configured
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
# Check for SITE_URL
|
|
if hasattr(settings, "SITE_URL"):
|
|
# Check if SITE_URL is empty
|
|
if settings.SITE_URL == "":
|
|
errors.append(
|
|
Error(
|
|
msg="'SITE_URL' is empty.",
|
|
hint="Make sure to set 'SITE_URL' to the URL of your Auth instance. (Without trailing slash)",
|
|
id="allianceauth.checks.B011",
|
|
)
|
|
)
|
|
# Check if SITE_URL has a trailing slash
|
|
elif settings.SITE_URL[-1] == "/":
|
|
errors.append(
|
|
Warning(
|
|
msg="'SITE_URL' has a trailing slash. This may lead to incorrect links being generated by Auth.",
|
|
hint="",
|
|
id="allianceauth.checks.B005",
|
|
)
|
|
)
|
|
# SITE_URL not found
|
|
else:
|
|
errors.append(
|
|
Error(
|
|
msg="No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules.",
|
|
hint="",
|
|
id="allianceauth.checks.B006",
|
|
)
|
|
)
|
|
|
|
# Check for CSRF_TRUSTED_ORIGINS
|
|
if hasattr(settings, "CSRF_TRUSTED_ORIGINS") and hasattr(settings, "SITE_URL"):
|
|
# Check if SITE_URL is not in CSRF_TRUSTED_ORIGINS
|
|
if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS:
|
|
errors.append(
|
|
Warning(
|
|
msg="'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified.",
|
|
hint="",
|
|
id="allianceauth.checks.B007",
|
|
)
|
|
)
|
|
# CSRF_TRUSTED_ORIGINS not found
|
|
else:
|
|
errors.append(
|
|
Error(
|
|
msg="No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified",
|
|
hint="",
|
|
id="allianceauth.checks.B008",
|
|
)
|
|
)
|
|
|
|
# Check for ESI_USER_CONTACT_EMAIL
|
|
if hasattr(settings, "ESI_USER_CONTACT_EMAIL"):
|
|
# Check if ESI_USER_CONTACT_EMAIL is empty
|
|
if settings.ESI_USER_CONTACT_EMAIL == "":
|
|
errors.append(
|
|
Error(
|
|
msg="'ESI_USER_CONTACT_EMAIL' is empty. A valid email is required as maintainer contact for CCP.",
|
|
hint="",
|
|
id="allianceauth.checks.B009",
|
|
)
|
|
)
|
|
# ESI_USER_CONTACT_EMAIL not found
|
|
else:
|
|
errors.append(
|
|
Error(
|
|
msg="No 'ESI_USER_CONTACT_EMAIL' found is settings. A valid email is required as maintainer contact for CCP.",
|
|
hint="",
|
|
id="allianceauth.checks.B010",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def system_package_redis(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that Redis is a supported version
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
allianceauth_redis_install_link = "https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools"
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
try:
|
|
redis_version = Pep440Version(get_redis_client().info()["redis_version"])
|
|
except InvalidVersion:
|
|
errors.append(Warning("Unable to confirm Redis Version"))
|
|
|
|
return errors
|
|
|
|
if (
|
|
redis_version.major == 7
|
|
and redis_version.minor == 2
|
|
and timezone.now()
|
|
> timezone.datetime(year=2025, month=8, day=31, tzinfo=timezone.utc)
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
|
hint=allianceauth_redis_install_link,
|
|
id="allianceauth.checks.A001",
|
|
)
|
|
)
|
|
elif redis_version.major == 7 and redis_version.minor == 0:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
|
hint=allianceauth_redis_install_link,
|
|
id="allianceauth.checks.A002",
|
|
)
|
|
)
|
|
elif redis_version.major == 6 and redis_version.minor == 2:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
|
hint=allianceauth_redis_install_link,
|
|
id="allianceauth.checks.A018",
|
|
)
|
|
)
|
|
elif redis_version.major in [6, 5]:
|
|
errors.append(
|
|
Error(
|
|
msg=f"Redis {redis_version.public} EOL",
|
|
hint=allianceauth_redis_install_link,
|
|
id="allianceauth.checks.A003",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def system_package_mysql(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that MySQL is a supported version
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
mysql_quick_guide_link = "https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/"
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
for connection in db.connections.all():
|
|
if connection.vendor == "mysql":
|
|
try:
|
|
mysql_version = Pep440Version(
|
|
".".join(str(i) for i in connection.mysql_version)
|
|
)
|
|
except InvalidVersion:
|
|
errors.append(Warning("Unable to confirm MySQL Version"))
|
|
|
|
return errors
|
|
|
|
# MySQL 8
|
|
if mysql_version.major == 8:
|
|
if mysql_version.minor == 4 and timezone.now() > timezone.datetime(
|
|
year=2032, month=4, day=30, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MySQL {mysql_version.public} EOL",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A004",
|
|
)
|
|
)
|
|
elif mysql_version.minor == 3:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"MySQL {mysql_version.public} Non LTS",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A005",
|
|
)
|
|
)
|
|
elif mysql_version.minor == 2:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"MySQL {mysql_version.public} Non LTS",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A006",
|
|
)
|
|
)
|
|
elif mysql_version.minor == 1:
|
|
errors.append(
|
|
Error(
|
|
msg=f"MySQL {mysql_version.public} EOL",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A007",
|
|
)
|
|
)
|
|
elif mysql_version.minor == 0 and timezone.now() > timezone.datetime(
|
|
year=2026, month=4, day=30, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MySQL {mysql_version.public} EOL",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A008",
|
|
)
|
|
)
|
|
|
|
# MySQL below 8
|
|
# This will also catch Mariadb 5.x
|
|
elif mysql_version.major < 8:
|
|
errors.append(
|
|
Error(
|
|
msg=f"MySQL or MariaDB {mysql_version.public} EOL",
|
|
hint=mysql_quick_guide_link,
|
|
id="allianceauth.checks.A009",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def system_package_mariadb(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that MariaDB is a supported version
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
mariadb_download_link = "https://mariadb.org/download/?t=repo-config"
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
for connection in db.connections.all():
|
|
# TODO: Find a way to determine MySQL vs. MariaDB
|
|
if connection.vendor == "mysql":
|
|
try:
|
|
mariadb_version = Pep440Version(
|
|
".".join(str(i) for i in connection.mysql_version)
|
|
)
|
|
except InvalidVersion:
|
|
errors.append(Warning("Unable to confirm MariaDB Version"))
|
|
|
|
return errors
|
|
|
|
# MariaDB 11
|
|
if mariadb_version.major == 11:
|
|
if mariadb_version.minor == 4 and timezone.now() > timezone.datetime(
|
|
year=2029, month=5, day=19, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A010",
|
|
)
|
|
)
|
|
elif mariadb_version.minor == 2:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"MariaDB {mariadb_version.public} Non LTS",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A018",
|
|
)
|
|
)
|
|
|
|
if timezone.now() > timezone.datetime(
|
|
year=2024, month=11, day=21, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A011",
|
|
)
|
|
)
|
|
elif mariadb_version.minor == 1:
|
|
errors.append(
|
|
Warning(
|
|
msg=f"MariaDB {mariadb_version.public} Non LTS",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A019",
|
|
)
|
|
)
|
|
|
|
if timezone.now() > timezone.datetime(
|
|
year=2024, month=8, day=21, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A012",
|
|
)
|
|
)
|
|
# Demote versions down here once EOL
|
|
elif mariadb_version.minor in [0, 3]:
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A013",
|
|
)
|
|
)
|
|
|
|
# MariaDB 10
|
|
elif mariadb_version.major == 10:
|
|
if mariadb_version.minor == 11 and timezone.now() > timezone.datetime(
|
|
year=2028, month=2, day=10, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A014",
|
|
)
|
|
)
|
|
elif mariadb_version.minor == 6 and timezone.now() > timezone.datetime(
|
|
year=2026, month=7, day=6, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A0015",
|
|
)
|
|
)
|
|
elif mariadb_version.minor == 5 and timezone.now() > timezone.datetime(
|
|
year=2025, month=6, day=24, tzinfo=timezone.utc
|
|
):
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A016",
|
|
)
|
|
)
|
|
# Demote versions down here once EOL
|
|
elif mariadb_version.minor in [0, 1, 2, 3, 4, 7, 9, 10]:
|
|
errors.append(
|
|
Error(
|
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
|
hint=mariadb_download_link,
|
|
id="allianceauth.checks.A017",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def system_package_sqlite(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that SQLite is a supported version
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
for connection in db.connections.all():
|
|
if connection.vendor == "sqlite":
|
|
try:
|
|
sqlite_version = Pep440Version(
|
|
".".join(str(i) for i in sqlite_version_info)
|
|
)
|
|
except InvalidVersion:
|
|
errors.append(Warning("Unable to confirm SQLite Version"))
|
|
|
|
return errors
|
|
if sqlite_version.major == 3 and sqlite_version.minor < 27:
|
|
errors.append(
|
|
Error(
|
|
msg=f"SQLite {sqlite_version.public} Unsupported by Django",
|
|
hint="https://pkgs.org/download/sqlite3",
|
|
id="allianceauth.checks.A020",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def sql_settings(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that SQL settings are correctly configured
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
for connection in db.connections.all():
|
|
if connection.vendor == "mysql":
|
|
try:
|
|
if connection.settings_dict["OPTIONS"]["charset"] != "utf8mb4":
|
|
errors.append(
|
|
Error(
|
|
msg=f"SQL Charset is not set to utf8mb4 DB: {connection.alias}",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
|
id="allianceauth.checks.B001",
|
|
)
|
|
)
|
|
except KeyError:
|
|
errors.append(
|
|
Error(
|
|
msg=f"SQL Charset is not set to utf8mb4 DB: {connection.alias}",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
|
id="allianceauth.checks.B001",
|
|
)
|
|
)
|
|
|
|
# This hasn't actually been set on AA yet
|
|
# try:
|
|
# if (
|
|
# connection.settings_dict["OPTIONS"]["collation"]
|
|
# != "utf8mb4_unicode_ci"
|
|
# ):
|
|
# errors.append(
|
|
# Error(
|
|
# msg=f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}",
|
|
# hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
|
# id="allianceauth.checks.B001",
|
|
# )
|
|
# )
|
|
# except KeyError:
|
|
# errors.append(
|
|
# Error(
|
|
# msg=f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}",
|
|
# hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
|
# id="allianceauth.checks.B001",
|
|
# )
|
|
# )
|
|
|
|
# if connection.vendor == "sqlite":
|
|
|
|
return errors
|
|
|
|
|
|
@register()
|
|
def celery_settings(app_configs, **kwargs) -> List[CheckMessage]:
|
|
"""
|
|
Check that Celery settings are correctly configured
|
|
|
|
:param app_configs:
|
|
:type app_configs:
|
|
:param kwargs:
|
|
:type kwargs:
|
|
:return:
|
|
:rtype:
|
|
"""
|
|
|
|
errors: List[CheckMessage] = []
|
|
|
|
try:
|
|
if current_app.conf.broker_transport_options != {
|
|
"priority_steps": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
|
"queue_order_strategy": "priority",
|
|
}:
|
|
errors.append(
|
|
Error(
|
|
msg="Celery Priorities are not set correctly",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc",
|
|
id="allianceauth.checks.B003",
|
|
)
|
|
)
|
|
except KeyError:
|
|
errors.append(
|
|
Error(
|
|
msg="Celery Priorities are not set",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc",
|
|
id="allianceauth.checks.B003",
|
|
)
|
|
)
|
|
|
|
try:
|
|
if not current_app.conf.broker_connection_retry_on_startup:
|
|
errors.append(
|
|
Error(
|
|
msg="Celery broker_connection_retry_on_startup not set correctly",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280",
|
|
id="allianceauth.checks.B004",
|
|
)
|
|
)
|
|
except KeyError:
|
|
errors.append(
|
|
Error(
|
|
msg="Celery broker_connection_retry_on_startup not set",
|
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280",
|
|
id="allianceauth.checks.B004",
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
# IDEAS
|
|
|
|
# Any other celery things weve manually changed over the years
|
|
# I'd be happy to add Community App checks, old versions the owners dont want to support etc.
|
|
|
|
|
|
# Check Default Collation on DB
|
|
# Check Charset Collation on all tables
|