From 246600cb636619d632d19fa24d46d18e33bd2a87 Mon Sep 17 00:00:00 2001 From: Bogdan Peter Date: Tue, 11 Mar 2025 13:47:29 +0200 Subject: [PATCH 1/2] Add validation to Job schedule to prevent scheduling jobs every second --- dkron/admin.py | 2 ++ dkron/forms.py | 16 ++++++++++++++++ testapp/testapp/urls.py | 1 + testapp/tests/test_generic.py | 15 +++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 dkron/forms.py diff --git a/dkron/admin.py b/dkron/admin.py index 7b18143..1f717c6 100644 --- a/dkron/admin.py +++ b/dkron/admin.py @@ -8,6 +8,7 @@ from django.urls import reverse from django.utils.html import format_html from dkron import models, utils +from dkron.forms import JobForm class JobAdminForm(forms.ModelForm): @@ -53,6 +54,7 @@ class JobAdmin(admin.ModelAdmin): search_fields = ('name', 'schedule', 'command', 'description') list_filter = ('name', 'schedule', 'enabled', 'last_run_success', 'notify_on_error') actions = ['disable_jobs', 'enable_jobs'] + form = JobForm def has_dashboard_permission(self, request): return request.user.has_perm('dkron.can_use_dashboard') diff --git a/dkron/forms.py b/dkron/forms.py new file mode 100644 index 0000000..0f1ed33 --- /dev/null +++ b/dkron/forms.py @@ -0,0 +1,16 @@ +from django import forms +from dkron.models import Job + + +class JobForm(forms.ModelForm): + def clean_schedule(self): + data = self.cleaned_data["schedule"] + if data.startswith("*"): + raise forms.ValidationError( + "Job schedule cannot start with * as this will schedule a job to start every second and can have unintended consequences." + ) + return data + + class Meta: + model = Job + fields = "__all__" diff --git a/testapp/testapp/urls.py b/testapp/testapp/urls.py index 2a1c453..a39fcf0 100644 --- a/testapp/testapp/urls.py +++ b/testapp/testapp/urls.py @@ -13,6 +13,7 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + from django.contrib import admin from django.urls import path, include diff --git a/testapp/tests/test_generic.py b/testapp/tests/test_generic.py index 26aaf03..5df981e 100644 --- a/testapp/tests/test_generic.py +++ b/testapp/tests/test_generic.py @@ -17,6 +17,7 @@ from notifications import models as notify_models from dkron import admin, models, utils from dkron.apps import DkronConfig +from dkron.forms import JobForm PROXY_VIEW = 'dkron:proxy' JOBS_URL = 'http://dkron/v1/jobs' @@ -180,6 +181,20 @@ def test_sync_job(self, job_prefix=''): self.assertEqual(exc.exception.code, 500) self.assertEqual(exc.exception.message, 'Whatever') + def test_job_form(self, job_prefix=''): + form_data = {'name': 'job1', 'schedule': '* 0 1 * * *', 'command': 'echo test', "retries": 0} + form = JobForm(data=form_data) + self.assertEqual(form.is_valid(), False) + self.assertEquals( + form.errors['schedule'], + [ + "Job schedule cannot start with * as this will schedule a job to start every second and can have unintended consequences." + ], + ) + form_data = {'name': 'job1', 'schedule': '0 0 1 * * *', 'command': 'echo test', "retries": 0} + form = JobForm(data=form_data) + self.assertEqual(form.is_valid(), True) + def test_delete_job(self, job_prefix=''): j = models.Job.objects.create(name='job1') with mock.patch('requests.delete') as mp: From 7967cdd4393798535b534e31d55621fee79bcd07 Mon Sep 17 00:00:00 2001 From: Bogdan Peter Date: Tue, 11 Mar 2025 13:53:36 +0200 Subject: [PATCH 2/2] bump version --- dkron/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dkron/__init__.py b/dkron/__init__.py index 2e63ddc..2433edb 100644 --- a/dkron/__init__.py +++ b/dkron/__init__.py @@ -1,4 +1,4 @@ -__version__ = '1.2.0' +__version__ = '1.2.1' # set default_app_config when using django earlier than 3.2 try: