diff --git a/dbbackup/checks.py b/dbbackup/checks.py index 9fbf76c..20de12c 100644 --- a/dbbackup/checks.py +++ b/dbbackup/checks.py @@ -1,4 +1,5 @@ import re +from datetime import datetime from django.core.checks import Tags, Warning, register @@ -35,6 +36,46 @@ "settings.DBBACKUP_ADMINS", id="dbbackup.W006", ) +W007 = Warning( + "Invalid FILENAME_TEMPLATE parameter", + hint="settings.DBBACKUP_FILENAME_TEMPLATE must not contain slashes ('/'). " + "Did you mean to change the value for 'location'?", + id="dbbackup.W007", +) +W008 = Warning( + "Invalid MEDIA_FILENAME_TEMPLATE parameter", + hint="settings.DBBACKUP_MEDIA_FILENAME_TEMPLATE must not contain slashes ('/')" + "Did you mean to change the value for 'location'?", + id="dbbackup.W007", +) + + +def check_filename_templates(): + return _check_filename_template( + settings.FILENAME_TEMPLATE, + W007, + "db", + ) + _check_filename_template( + settings.MEDIA_FILENAME_TEMPLATE, + W008, + "media", + ) + + +def _check_filename_template(filename_template, check_code, content_type) -> list: + if callable(filename_template): + params = { + "servername": "localhost", + "datetime": datetime.now().strftime(settings.DATE_FORMAT), + "databasename": "default", + "extension": "dump", + "content_type": content_type, + } + filename_template = filename_template(params) + + if "/" in filename_template: + return [check_code] + return [] @register(Tags.compatibility) @@ -64,4 +105,6 @@ def check_settings(app_configs, **kwargs): if getattr(settings, "FAILURE_RECIPIENTS", None) is not None: errors.append(W006) + errors += check_filename_templates() + return errors diff --git a/dbbackup/tests/test_checks.py b/dbbackup/tests/test_checks.py index 2a58332..279abea 100644 --- a/dbbackup/tests/test_checks.py +++ b/dbbackup/tests/test_checks.py @@ -72,3 +72,27 @@ def test_Failure_recipients_warning(self): expected_errors = [checks.W006] errors = checks.check_settings(DbbackupConfig) self.assertEqual(expected_errors, errors) + + @patch("dbbackup.checks.settings.FILENAME_TEMPLATE", "foo/bar-{datetime}.ext") + def test_db_filename_template_with_slash(self): + expected_errors = [checks.W007] + errors = checks.check_settings(DbbackupConfig) + self.assertEqual(expected_errors, errors) + + @patch("dbbackup.checks.settings.FILENAME_TEMPLATE", lambda _: "foo/bar") + def test_db_filename_template_callable_with_slash(self): + expected_errors = [checks.W007] + errors = checks.check_settings(DbbackupConfig) + self.assertEqual(expected_errors, errors) + + @patch("dbbackup.checks.settings.MEDIA_FILENAME_TEMPLATE", "foo/bar-{datetime}.ext") + def test_media_filename_template_with_slash(self): + expected_errors = [checks.W008] + errors = checks.check_settings(DbbackupConfig) + self.assertEqual(expected_errors, errors) + + @patch("dbbackup.checks.settings.MEDIA_FILENAME_TEMPLATE", lambda _: "foo/bar") + def test_media_filename_template_callable_with_slash(self): + expected_errors = [checks.W008] + errors = checks.check_settings(DbbackupConfig) + self.assertEqual(expected_errors, errors) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4a12daf..b0384b9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,7 @@ Unreleased * Default HOST to localhost for postgres databases. https://github.com/jazzband/django-dbbackup/issues/520 * Add PostgreSQL Schema support by @angryfoxx in https://github.com/jazzband/django-dbbackup/pull/507 * Fix restore of database from S3 storage by reintroducing inputfile.seek(0) to utils.uncompress_file +* Add warning for filenames with slashes in them * Fix bug where dbbackup management command would not respect settings.py:DBBACKUP_DATABASES * Remove usage of deprecated 'get_storage_class' function in newer Django versions * Add support for new STORAGES (Django 4.2+) setting under the 'dbbackup' alias