diff mbox series

[layerindex-web] layerindex: use https for URLs entered without a scheme

Message ID 20261114070115.28388-1-tim.orling@konsulko.com
State Under Review
Delegated to: Tim Orling
Headers show
Series [layerindex-web] layerindex: use https for URLs entered without a scheme | expand

Commit Message

Tim Orling Nov. 14, 2026, 7:01 a.m. UTC
Django 5.2 warns that the URL form fields will assume https instead of
http for a URL entered without a scheme from Django 6.0. Say which one
the layer, bulk change and layer admin forms mean, choosing https as
Django 6.0 will, so that the behaviour doesn't change silently when
upgrading and the warning goes away.

[YOCTO #16498]

AI-Generated: Claude Opus 5.5
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
With this, the test suite runs without any warnings. The
FORMS_URLFIELD_ASSUME_HTTPS setting is not used because it is itself
deprecated and removed in Django 6.0. Applies to master and to
master-next.

 layerindex/admin.py      |  2 +-
 layerindex/forms.py      | 11 +++++++++++
 tests/test_url_fields.py | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 tests/test_url_fields.py


base-commit: 08e58cdece30019a6f9e5d14af16ebe20afa6177
diff mbox series

Patch

diff --git a/layerindex/admin.py b/layerindex/admin.py
index f8b2f6e..61ac3e7 100644
--- a/layerindex/admin.py
+++ b/layerindex/admin.py
@@ -55,7 +55,7 @@  class LayerItemAdmin(CompareVersionAdmin):
     save_as = True
     search_fields = ['name', 'summary', 'vcs_url']
     formfield_overrides = {
-        models.URLField: {'widget': TextInput(attrs={'size':'100'})},
+        models.URLField: {'widget': TextInput(attrs={'size':'100'}), 'assume_scheme': 'https'},
         models.CharField: {'widget': TextInput(attrs={'size':'100'})},
     }
 
diff --git a/layerindex/forms.py b/layerindex/forms.py
index 733adc2..bd857ff 100644
--- a/layerindex/forms.py
+++ b/layerindex/forms.py
@@ -11,6 +11,7 @@  from collections import OrderedDict
 
 from captcha.fields import CaptchaField
 from django import forms
+from django.db import models
 from django.contrib.auth.models import User
 from django.core.cache import cache
 from django.core.validators import EmailValidator, RegexValidator, URLValidator
@@ -35,6 +36,14 @@  class StyledForm(forms.Form):
         for visible in self.visible_fields():
             visible.field.widget.attrs['class'] = 'form-control'
 
+def https_url_formfield(field, **kwargs):
+    """Model form field callback: treat a URL entered without a scheme as
+    https, as Django 6.0 will by default, rather than http"""
+    if isinstance(field, models.URLField):
+        kwargs.setdefault('assume_scheme', 'https')
+    return field.formfield(**kwargs)
+
+
 class StyledModelForm(forms.ModelForm):
     # Ensure form-control class for Bootstrap 3 is applied to Django-generated widgets
     def __init__(self, *args, **kwargs):
@@ -85,6 +94,7 @@  class EditLayerForm(StyledModelForm):
     class Meta:
         model = LayerItem
         fields = ('name', 'layer_type', 'summary', 'description', 'vcs_url', 'vcs_web_url', 'vcs_web_tree_base_url', 'vcs_web_file_base_url', 'vcs_web_commit_url', 'usage_url', 'mailing_list_url')
+        formfield_callback = https_url_formfield
 
     def __init__(self, user, layerbranch, allow_base_type, *args, **kwargs):
         super(self.__class__, self).__init__(*args, **kwargs)
@@ -332,6 +342,7 @@  class BulkChangeEditForm(StyledModelForm):
     class Meta:
         model = RecipeChange
         fields = ('summary', 'description', 'homepage', 'bugtracker', 'section', 'license')
+        formfield_callback = https_url_formfield
 
 BulkChangeEditFormSet = modelformset_factory(RecipeChange, form=BulkChangeEditForm, extra=0)
 
diff --git a/tests/test_url_fields.py b/tests/test_url_fields.py
new file mode 100644
index 0000000..443cb6c
--- /dev/null
+++ b/tests/test_url_fields.py
@@ -0,0 +1,36 @@ 
+# layerindex-web - URL form fields use https for a URL entered without a scheme
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import importlib
+import warnings
+
+from django import forms
+from django.contrib import admin
+from django.utils.deprecation import RemovedInDjango60Warning
+
+import layerindex.forms
+from layerindex.models import LayerItem
+
+
+def test_url_form_fields_assume_https(rf, admin_user):
+    # [YOCTO #16498] create the form classes again, to see any warning
+    with warnings.catch_warnings():
+        warnings.simplefilter('error', RemovedInDjango60Warning)
+        mod = importlib.reload(layerindex.forms)
+        request = rf.get('/')
+        request.user = admin_user
+        admin_form = admin.site._registry[LayerItem].get_form(request)
+
+    url_fields = [
+        mod.EditLayerForm.base_fields['vcs_web_url'],
+        mod.EditLayerForm.base_fields['mailing_list_url'],
+        mod.BulkChangeEditForm.base_fields['homepage'],
+        mod.BulkChangeEditForm.base_fields['bugtracker'],
+        admin_form.base_fields['vcs_web_url'],
+    ]
+    for field in url_fields:
+        assert isinstance(field, forms.URLField)
+        assert field.clean('github.com/example/meta-example') == 'https://github.com/example/meta-example'