*: allow URLs without domain and custom schemas
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
		| @ -3,7 +3,6 @@ | ||||
| import uuid | ||||
| from os import environ | ||||
|  | ||||
| import django.core.validators | ||||
| import django.db.models.deletion | ||||
| from django.apps.registry import Apps | ||||
| from django.conf import settings | ||||
| @ -12,6 +11,7 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||
| from django.db.models import Count | ||||
|  | ||||
| import authentik.core.models | ||||
| import authentik.lib.models | ||||
|  | ||||
|  | ||||
| def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | ||||
| @ -161,7 +161,7 @@ class Migration(migrations.Migration): | ||||
|             model_name="application", | ||||
|             name="meta_launch_url", | ||||
|             field=models.TextField( | ||||
|                 blank=True, default="", validators=[django.core.validators.URLValidator()] | ||||
|                 blank=True, default="", validators=[authentik.lib.models.DomainlessURLValidator()] | ||||
|             ), | ||||
|         ), | ||||
|         migrations.RunPython( | ||||
|  | ||||
| @ -1,8 +1,9 @@ | ||||
| # Generated by Django 3.2.3 on 2021-06-02 21:51 | ||||
|  | ||||
| import django.core.validators | ||||
| from django.db import migrations, models | ||||
|  | ||||
| import authentik.lib.models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
| @ -17,7 +18,7 @@ class Migration(migrations.Migration): | ||||
|             field=models.TextField( | ||||
|                 blank=True, | ||||
|                 default="", | ||||
|                 validators=[django.core.validators.URLValidator()], | ||||
|                 validators=[authentik.lib.models.DomainlessURLValidator()], | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -9,7 +9,6 @@ from deepmerge import always_merger | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import AbstractUser | ||||
| from django.contrib.auth.models import UserManager as DjangoUserManager | ||||
| from django.core import validators | ||||
| from django.db import models | ||||
| from django.db.models import Q, QuerySet, options | ||||
| from django.http import HttpRequest | ||||
| @ -29,7 +28,7 @@ from authentik.core.types import UILoginButton, UserSettingSerializer | ||||
| from authentik.flows.models import Flow | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.generators import generate_id | ||||
| from authentik.lib.models import CreatedUpdatedModel, SerializerModel | ||||
| from authentik.lib.models import CreatedUpdatedModel, DomainlessURLValidator, SerializerModel | ||||
| from authentik.lib.utils.http import get_client_ip | ||||
| from authentik.managed.models import ManagedModel | ||||
| from authentik.policies.models import PolicyBindingModel | ||||
| @ -246,7 +245,7 @@ class Application(PolicyBindingModel): | ||||
|     ) | ||||
|  | ||||
|     meta_launch_url = models.TextField( | ||||
|         default="", blank=True, validators=[validators.URLValidator()] | ||||
|         default="", blank=True, validators=[DomainlessURLValidator()] | ||||
|     ) | ||||
|     # For template applications, this can be set to /static/authentik/applications/* | ||||
|     meta_icon = models.FileField( | ||||
|  | ||||
| @ -22,7 +22,7 @@ def create_test_flow(designation: FlowDesignation = FlowDesignation.STAGE_CONFIG | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def create_test_admin_user(name: Optional[str] = None, set_password=False) -> User: | ||||
| def create_test_admin_user(name: Optional[str] = None) -> User: | ||||
|     """Generate a test-admin user""" | ||||
|     uid = generate_id(20) if not name else name | ||||
|     group = Group.objects.create(name=uid, is_superuser=True) | ||||
|  | ||||
| @ -4,7 +4,6 @@ import uuid | ||||
| from datetime import timedelta | ||||
| from typing import Iterable | ||||
|  | ||||
| import django.core.validators | ||||
| import django.db.models.deletion | ||||
| from django.apps.registry import Apps | ||||
| from django.conf import settings | ||||
| @ -12,6 +11,7 @@ from django.db import migrations, models | ||||
| from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||
|  | ||||
| import authentik.events.models | ||||
| import authentik.lib.models | ||||
| from authentik.events.models import EventAction, NotificationSeverity, TransportMode | ||||
|  | ||||
|  | ||||
| @ -826,6 +826,8 @@ class Migration(migrations.Migration): | ||||
|         migrations.AlterField( | ||||
|             model_name="notificationtransport", | ||||
|             name="webhook_url", | ||||
|             field=models.TextField(blank=True, validators=[django.core.validators.URLValidator()]), | ||||
|             field=models.TextField( | ||||
|                 blank=True, validators=[authentik.lib.models.DomainlessURLValidator()] | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -1,8 +1,9 @@ | ||||
| # Generated by Django 3.2.7 on 2021-10-04 15:31 | ||||
|  | ||||
| import django.core.validators | ||||
| from django.db import migrations, models | ||||
|  | ||||
| import authentik.lib.models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
| @ -14,6 +15,8 @@ class Migration(migrations.Migration): | ||||
|         migrations.AlterField( | ||||
|             model_name="notificationtransport", | ||||
|             name="webhook_url", | ||||
|             field=models.TextField(blank=True, validators=[django.core.validators.URLValidator()]), | ||||
|             field=models.TextField( | ||||
|                 blank=True, validators=[authentik.lib.models.DomainlessURLValidator()] | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -6,7 +6,6 @@ from typing import TYPE_CHECKING, Optional, Type, Union | ||||
| from uuid import uuid4 | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.validators import URLValidator | ||||
| from django.db import models | ||||
| from django.http import HttpRequest | ||||
| from django.http.request import QueryDict | ||||
| @ -20,6 +19,7 @@ from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION | ||||
| from authentik.core.models import ExpiringModel, Group, PropertyMapping, User | ||||
| from authentik.events.geo import GEOIP_READER | ||||
| from authentik.events.utils import cleanse_dict, get_user, model_to_dict, sanitize_dict | ||||
| from authentik.lib.models import DomainlessURLValidator | ||||
| from authentik.lib.sentry import SentryIgnoredException | ||||
| from authentik.lib.utils.http import get_client_ip, get_http_session | ||||
| from authentik.lib.utils.time import timedelta_from_string | ||||
| @ -224,7 +224,7 @@ class NotificationTransport(models.Model): | ||||
|     name = models.TextField(unique=True) | ||||
|     mode = models.TextField(choices=TransportMode.choices) | ||||
|  | ||||
|     webhook_url = models.TextField(blank=True, validators=[URLValidator()]) | ||||
|     webhook_url = models.TextField(blank=True, validators=[DomainlessURLValidator()]) | ||||
|     webhook_mapping = models.ForeignKey( | ||||
|         "NotificationWebhookMapping", on_delete=models.SET_DEFAULT, null=True, default=None | ||||
|     ) | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| """Generic models""" | ||||
| import re | ||||
|  | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.core.validators import URLValidator | ||||
| from django.db import models | ||||
| from django.utils.regex_helper import _lazy_re_compile | ||||
| @ -66,3 +67,11 @@ class DomainlessURLValidator(URLValidator): | ||||
|             r"\Z", | ||||
|             re.IGNORECASE, | ||||
|         ) | ||||
|         self.schemes = ["http", "https", "blank"] | ||||
|  | ||||
|     def __call__(self, value): | ||||
|         # Check if the scheme is valid. | ||||
|         scheme = value.split("://")[0].lower() | ||||
|         if scheme not in self.schemes: | ||||
|             value = "default" + value | ||||
|         return super().__call__(value) | ||||
|  | ||||
| @ -61,7 +61,7 @@ class SeleniumTestCase(ChannelsLiveServerTestCase): | ||||
|         self.driver.implicitly_wait(30) | ||||
|         self.wait = WebDriverWait(self.driver, self.wait_timeout) | ||||
|         self.logger = get_logger() | ||||
|         self.user = create_test_admin_user(set_password=True) | ||||
|         self.user = create_test_admin_user() | ||||
|         if specs := self.get_container_specs(): | ||||
|             self.container = self._start_container(specs) | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer