*: use py3.10 syntax for unions, remove old Type[] import when possible

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-12-30 14:59:01 +01:00
parent 1e1876b34c
commit c249b55ff5
49 changed files with 92 additions and 110 deletions

View File

@ -1,7 +1,7 @@
"""API Authentication""" """API Authentication"""
from base64 import b64decode from base64 import b64decode
from binascii import Error from binascii import Error
from typing import Any, Optional, Union from typing import Any, Optional
from django.conf import settings from django.conf import settings
from rest_framework.authentication import BaseAuthentication, get_authorization_header from rest_framework.authentication import BaseAuthentication, get_authorization_header
@ -69,7 +69,7 @@ def token_secret_key(value: str) -> Optional[User]:
class TokenAuthentication(BaseAuthentication): class TokenAuthentication(BaseAuthentication):
"""Token-based authentication using HTTP Bearer authentication""" """Token-based authentication using HTTP Bearer authentication"""
def authenticate(self, request: Request) -> Union[tuple[User, Any], None]: def authenticate(self, request: Request) -> tuple[User, Any] | None:
"""Token-based authentication using HTTP Bearer authentication""" """Token-based authentication using HTTP Bearer authentication"""
auth = get_authorization_header(request) auth = get_authorization_header(request)

View File

@ -15,7 +15,6 @@ import authentik.lib.models
def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
from django.contrib.sessions.backends.cache import KEY_PREFIX from django.contrib.sessions.backends.cache import KEY_PREFIX
from django.core.cache import cache from django.core.cache import cache

View File

@ -12,7 +12,6 @@ import authentik.core.models
def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
from django.contrib.sessions.backends.cache import KEY_PREFIX from django.contrib.sessions.backends.cache import KEY_PREFIX
from django.core.cache import cache from django.core.cache import cache

View File

@ -1,7 +1,7 @@
"""authentik core models""" """authentik core models"""
from datetime import timedelta from datetime import timedelta
from hashlib import md5, sha256 from hashlib import md5, sha256
from typing import Any, Optional, Type from typing import Any, Optional
from urllib.parse import urlencode from urllib.parse import urlencode
from uuid import uuid4 from uuid import uuid4
@ -224,7 +224,7 @@ class Provider(SerializerModel):
raise NotImplementedError raise NotImplementedError
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
"""Get serializer for this model""" """Get serializer for this model"""
raise NotImplementedError raise NotImplementedError
@ -505,7 +505,7 @@ class PropertyMapping(SerializerModel, ManagedModel):
raise NotImplementedError raise NotImplementedError
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
"""Get serializer for this model""" """Get serializer for this model"""
raise NotImplementedError raise NotImplementedError

View File

@ -1,5 +1,5 @@
"""authentik core signals""" """authentik core signals"""
from typing import TYPE_CHECKING, Type from typing import TYPE_CHECKING
from django.contrib.auth.signals import user_logged_in, user_logged_out from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.contrib.sessions.backends.cache import KEY_PREFIX from django.contrib.sessions.backends.cache import KEY_PREFIX
@ -62,7 +62,7 @@ def user_logged_out_session(sender, request: HttpRequest, user: "User", **_):
@receiver(pre_delete) @receiver(pre_delete)
def authenticated_session_delete(sender: Type[Model], instance: "AuthenticatedSession", **_): def authenticated_session_delete(sender: type[Model], instance: "AuthenticatedSession", **_):
"""Delete session when authenticated session is deleted""" """Delete session when authenticated session is deleted"""
from authentik.core.models import AuthenticatedSession from authentik.core.models import AuthenticatedSession

View File

@ -1,6 +1,6 @@
"""Source decision helper""" """Source decision helper"""
from enum import Enum from enum import Enum
from typing import Any, Optional, Type from typing import Any, Optional
from django.contrib import messages from django.contrib import messages
from django.db import IntegrityError from django.db import IntegrityError
@ -50,7 +50,7 @@ class SourceFlowManager:
identifier: str identifier: str
connection_type: Type[UserSourceConnection] = UserSourceConnection connection_type: type[UserSourceConnection] = UserSourceConnection
def __init__( def __init__(
self, self,

View File

@ -1,6 +1,6 @@
"""authentik core models tests""" """authentik core models tests"""
from time import sleep from time import sleep
from typing import Callable, Type from typing import Callable
from django.test import RequestFactory, TestCase from django.test import RequestFactory, TestCase
from django.utils.timezone import now from django.utils.timezone import now
@ -27,7 +27,7 @@ class TestModels(TestCase):
self.assertFalse(token.is_expired) self.assertFalse(token.is_expired)
def source_tester_factory(test_model: Type[Stage]) -> Callable: def source_tester_factory(test_model: type[Stage]) -> Callable:
"""Test source""" """Test source"""
factory = RequestFactory() factory = RequestFactory()
@ -47,7 +47,7 @@ def source_tester_factory(test_model: Type[Stage]) -> Callable:
return tester return tester
def provider_tester_factory(test_model: Type[Stage]) -> Callable: def provider_tester_factory(test_model: type[Stage]) -> Callable:
"""Test provider""" """Test provider"""
def tester(self: TestModels): def tester(self: TestModels):

View File

@ -1,7 +1,7 @@
"""authentik crypto models""" """authentik crypto models"""
from binascii import hexlify from binascii import hexlify
from hashlib import md5 from hashlib import md5
from typing import Optional, Union from typing import Optional
from uuid import uuid4 from uuid import uuid4
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
@ -41,8 +41,8 @@ class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
) )
_cert: Optional[Certificate] = None _cert: Optional[Certificate] = None
_private_key: Optional[Union[RSAPrivateKey, EllipticCurvePrivateKey, Ed25519PrivateKey]] = None _private_key: Optional[RSAPrivateKey | EllipticCurvePrivateKey | Ed25519PrivateKey] = None
_public_key: Optional[Union[RSAPublicKey, EllipticCurvePublicKey, Ed25519PublicKey]] = None _public_key: Optional[RSAPublicKey | EllipticCurvePublicKey | Ed25519PublicKey] = None
@property @property
def certificate(self) -> Certificate: def certificate(self) -> Certificate:
@ -54,7 +54,7 @@ class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
return self._cert return self._cert
@property @property
def public_key(self) -> Optional[Union[RSAPublicKey, EllipticCurvePublicKey, Ed25519PublicKey]]: def public_key(self) -> Optional[RSAPublicKey | EllipticCurvePublicKey | Ed25519PublicKey]:
"""Get public key of the private key""" """Get public key of the private key"""
if not self._public_key: if not self._public_key:
self._public_key = self.private_key.public_key() self._public_key = self.private_key.public_key()
@ -63,7 +63,7 @@ class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
@property @property
def private_key( def private_key(
self, self,
) -> Optional[Union[RSAPrivateKey, EllipticCurvePrivateKey, Ed25519PrivateKey]]: ) -> Optional[RSAPrivateKey | EllipticCurvePrivateKey | Ed25519PrivateKey]:
"""Get python cryptography PrivateKey instance""" """Get python cryptography PrivateKey instance"""
if not self._private_key and self.key_data != "": if not self._private_key and self.key_data != "":
try: try:

View File

@ -19,7 +19,7 @@ def convert_user_to_json(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
Event = apps.get_model("authentik_events", "Event") Event = apps.get_model("authentik_events", "Event")
db_alias = schema_editor.connection.alias db_alias = schema_editor.connection.alias
for event in Event.objects.all(): for event in Event.objects.using(db_alias).all():
event.delete() event.delete()
# Because event objects cannot be updated, we have to re-create them # Because event objects cannot be updated, we have to re-create them
event.pk = None event.pk = None

View File

@ -10,7 +10,7 @@ def convert_user_to_json(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
Event = apps.get_model("authentik_events", "Event") Event = apps.get_model("authentik_events", "Event")
db_alias = schema_editor.connection.alias db_alias = schema_editor.connection.alias
for event in Event.objects.all(): for event in Event.objects.using(db_alias).all():
event.delete() event.delete()
# Because event objects cannot be updated, we have to re-create them # Because event objects cannot be updated, we have to re-create them
event.pk = None event.pk = None

View File

@ -4,7 +4,7 @@ from collections import Counter
from datetime import timedelta from datetime import timedelta
from inspect import currentframe from inspect import currentframe
from smtplib import SMTPException from smtplib import SMTPException
from typing import TYPE_CHECKING, Optional, Type, Union from typing import TYPE_CHECKING, Optional
from uuid import uuid4 from uuid import uuid4
from django.conf import settings from django.conf import settings
@ -190,7 +190,7 @@ class Event(ExpiringModel):
@staticmethod @staticmethod
def new( def new(
action: Union[str, EventAction], action: str | EventAction,
app: Optional[str] = None, app: Optional[str] = None,
**kwargs, **kwargs,
) -> "Event": ) -> "Event":
@ -517,7 +517,7 @@ class NotificationWebhookMapping(PropertyMapping):
return "ak-property-mapping-notification-form" return "ak-property-mapping-notification-form"
@property @property
def serializer(self) -> Type["Serializer"]: def serializer(self) -> type["Serializer"]:
from authentik.events.api.notification_mapping import NotificationWebhookMappingSerializer from authentik.events.api.notification_mapping import NotificationWebhookMappingSerializer
return NotificationWebhookMappingSerializer return NotificationWebhookMappingSerializer

View File

@ -1,7 +1,7 @@
"""Flow models""" """Flow models"""
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from pickle import dumps, loads # nosec from pickle import dumps, loads # nosec
from typing import TYPE_CHECKING, Optional, Type from typing import TYPE_CHECKING, Optional
from uuid import uuid4 from uuid import uuid4
from django.db import models from django.db import models
@ -63,7 +63,7 @@ class Stage(SerializerModel):
objects = InheritanceManager() objects = InheritanceManager()
@property @property
def type(self) -> Type["StageView"]: def type(self) -> type["StageView"]:
"""Return StageView class that implements logic for this stage""" """Return StageView class that implements logic for this stage"""
# This is a bit of a workaround, since we can't set class methods with setattr # This is a bit of a workaround, since we can't set class methods with setattr
if hasattr(self, "__in_memory_type"): if hasattr(self, "__in_memory_type"):
@ -86,7 +86,7 @@ class Stage(SerializerModel):
return f"Stage {self.name}" return f"Stage {self.name}"
def in_memory_stage(view: Type["StageView"]) -> Stage: def in_memory_stage(view: type["StageView"]) -> Stage:
"""Creates an in-memory stage instance, based on a `view` as view.""" """Creates an in-memory stage instance, based on a `view` as view."""
stage = Stage() stage = Stage()
# Because we can't pickle a locally generated function, # Because we can't pickle a locally generated function,

View File

@ -1,5 +1,5 @@
"""base model tests""" """base model tests"""
from typing import Callable, Type from typing import Callable
from django.test import TestCase from django.test import TestCase
@ -12,7 +12,7 @@ class TestModels(TestCase):
"""Generic model properties tests""" """Generic model properties tests"""
def model_tester_factory(test_model: Type[Stage]) -> Callable: def model_tester_factory(test_model: type[Stage]) -> Callable:
"""Test a form""" """Test a form"""
def tester(self: TestModels): def tester(self: TestModels):

View File

@ -1,5 +1,5 @@
"""stage view tests""" """stage view tests"""
from typing import Callable, Type from typing import Callable
from django.test import RequestFactory, TestCase from django.test import RequestFactory, TestCase
@ -16,7 +16,7 @@ class TestViews(TestCase):
self.exec = FlowExecutorView(request=self.factory.get("/")) self.exec = FlowExecutorView(request=self.factory.get("/"))
def view_tester_factory(view_class: Type[StageView]) -> Callable: def view_tester_factory(view_class: type[StageView]) -> Callable:
"""Test a form""" """Test a form"""
def tester(self: TestViews): def tester(self: TestViews):

View File

@ -2,7 +2,7 @@
from contextlib import contextmanager from contextlib import contextmanager
from copy import deepcopy from copy import deepcopy
from json import loads from json import loads
from typing import Any, Type from typing import Any
from dacite import from_dict from dacite import from_dict
from dacite.exceptions import DaciteError from dacite.exceptions import DaciteError
@ -87,7 +87,7 @@ class FlowImporter:
def _validate_single(self, entry: FlowBundleEntry) -> BaseSerializer: def _validate_single(self, entry: FlowBundleEntry) -> BaseSerializer:
"""Validate a single entry""" """Validate a single entry"""
model_app_label, model_name = entry.model.split(".") model_app_label, model_name = entry.model.split(".")
model: Type[SerializerModel] = apps.get_model(model_app_label, model_name) model: type[SerializerModel] = apps.get_model(model_app_label, model_name)
if not isinstance(model(), ALLOWED_MODELS): if not isinstance(model(), ALLOWED_MODELS):
raise EntryInvalidError(f"Model {model} not allowed") raise EntryInvalidError(f"Model {model} not allowed")

View File

@ -1,5 +1,5 @@
"""base model tests""" """base model tests"""
from typing import Callable, Type from typing import Callable
from django.test import TestCase from django.test import TestCase
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
@ -13,7 +13,7 @@ class TestModels(TestCase):
"""Generic model properties tests""" """Generic model properties tests"""
def model_tester_factory(test_model: Type[Stage]) -> Callable: def model_tester_factory(test_model: type[Stage]) -> Callable:
"""Test a form""" """Test a form"""
def tester(self: TestModels): def tester(self: TestModels):

View File

@ -2,7 +2,6 @@
import os import os
from importlib import import_module from importlib import import_module
from pathlib import Path from pathlib import Path
from typing import Union
from django.conf import settings from django.conf import settings
from kubernetes.config.incluster_config import SERVICE_HOST_ENV_NAME from kubernetes.config.incluster_config import SERVICE_HOST_ENV_NAME
@ -30,7 +29,7 @@ def class_to_path(cls: type) -> str:
return f"{cls.__module__}.{cls.__name__}" return f"{cls.__module__}.{cls.__name__}"
def path_to_class(path: Union[str, None]) -> Union[type, None]: def path_to_class(path: str | None) -> type | None:
"""Import module and return class""" """Import module and return class"""
if not path: if not path:
return None return None

View File

@ -1,5 +1,5 @@
"""Managed objects manager""" """Managed objects manager"""
from typing import Callable, Optional, Type from typing import Callable, Optional
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -11,11 +11,11 @@ LOGGER = get_logger()
class EnsureOp: class EnsureOp:
"""Ensure operation, executed as part of an ObjectManager run""" """Ensure operation, executed as part of an ObjectManager run"""
_obj: Type[ManagedModel] _obj: type[ManagedModel]
_managed_uid: str _managed_uid: str
_kwargs: dict _kwargs: dict
def __init__(self, obj: Type[ManagedModel], managed_uid: str, **kwargs) -> None: def __init__(self, obj: type[ManagedModel], managed_uid: str, **kwargs) -> None:
self._obj = obj self._obj = obj
self._managed_uid = managed_uid self._managed_uid = managed_uid
self._kwargs = kwargs self._kwargs = kwargs
@ -32,7 +32,7 @@ class EnsureExists(EnsureOp):
def __init__( def __init__(
self, self,
obj: Type[ManagedModel], obj: type[ManagedModel],
managed_uid: str, managed_uid: str,
created_callback: Optional[Callable] = None, created_callback: Optional[Callable] = None,
**kwargs, **kwargs,

View File

@ -1,6 +1,5 @@
"""Kubernetes deployment controller""" """Kubernetes deployment controller"""
from io import StringIO from io import StringIO
from typing import Type
from kubernetes.client import VersionApi, VersionInfo from kubernetes.client import VersionApi, VersionInfo
from kubernetes.client.api_client import ApiClient from kubernetes.client.api_client import ApiClient
@ -54,7 +53,7 @@ class KubernetesClient(ApiClient, BaseClient):
class KubernetesController(BaseController): class KubernetesController(BaseController):
"""Manage deployment of outpost in kubernetes""" """Manage deployment of outpost in kubernetes"""
reconcilers: dict[str, Type[KubernetesObjectReconciler]] reconcilers: dict[str, type[KubernetesObjectReconciler]]
reconcile_order: list[str] reconcile_order: list[str]
client: KubernetesClient client: KubernetesClient

View File

@ -2,7 +2,7 @@
from dataclasses import asdict, dataclass, field from dataclasses import asdict, dataclass, field
from datetime import datetime from datetime import datetime
from os import environ from os import environ
from typing import Iterable, Optional, Union from typing import Iterable, Optional
from uuid import uuid4 from uuid import uuid4
from dacite import from_dict from dacite import from_dict
@ -76,7 +76,7 @@ class OutpostConfig:
class OutpostModel(Model): class OutpostModel(Model):
"""Base model for providers that need more objects than just themselves""" """Base model for providers that need more objects than just themselves"""
def get_required_objects(self) -> Iterable[Union[models.Model, str]]: def get_required_objects(self) -> Iterable[models.Model | str]:
"""Return a list of all required objects""" """Return a list of all required objects"""
return [self] return [self]
@ -375,9 +375,9 @@ class Outpost(ManagedModel):
Token.objects.filter(identifier=self.token_identifier).delete() Token.objects.filter(identifier=self.token_identifier).delete()
return self.token return self.token
def get_required_objects(self) -> Iterable[Union[models.Model, str]]: def get_required_objects(self) -> Iterable[models.Model | str]:
"""Get an iterator of all objects the user needs read access to""" """Get an iterator of all objects the user needs read access to"""
objects: list[Union[models.Model, str]] = [ objects: list[models.Model | str] = [
self, self,
"authentik_events.add_event", "authentik_events.add_event",
] ]
@ -404,7 +404,7 @@ class OutpostState:
channel_ids: list[str] = field(default_factory=list) channel_ids: list[str] = field(default_factory=list)
last_seen: Optional[datetime] = field(default=None) last_seen: Optional[datetime] = field(default=None)
version: Optional[str] = field(default=None) version: Optional[str] = field(default=None)
version_should: Union[Version, LegacyVersion] = field(default=OUR_VERSION) version_should: Version | LegacyVersion = field(default=OUR_VERSION)
build_hash: str = field(default="") build_hash: str = field(default="")
_outpost: Optional[Outpost] = field(default=None) _outpost: Optional[Outpost] = field(default=None)

View File

@ -1,5 +1,5 @@
"""LDAP Provider""" """LDAP Provider"""
from typing import Iterable, Optional, Type, Union from typing import Iterable, Optional
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -78,7 +78,7 @@ class LDAPProvider(OutpostModel, Provider):
return "ak-provider-ldap-form" return "ak-provider-ldap-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.ldap.api import LDAPProviderSerializer from authentik.providers.ldap.api import LDAPProviderSerializer
return LDAPProviderSerializer return LDAPProviderSerializer
@ -86,7 +86,7 @@ class LDAPProvider(OutpostModel, Provider):
def __str__(self): def __str__(self):
return f"LDAP Provider {self.name}" return f"LDAP Provider {self.name}"
def get_required_objects(self) -> Iterable[Union[models.Model, str]]: def get_required_objects(self) -> Iterable[models.Model | str]:
required_models = [self, "authentik_core.view_user", "authentik_core.view_group"] required_models = [self, "authentik_core.view_user", "authentik_core.view_group"]
if self.certificate is not None: if self.certificate is not None:
required_models.append(self.certificate) required_models.append(self.certificate)

View File

@ -6,7 +6,7 @@ import time
from dataclasses import asdict, dataclass, field from dataclasses import asdict, dataclass, field
from datetime import datetime from datetime import datetime
from hashlib import sha256 from hashlib import sha256
from typing import Any, Optional, Type from typing import Any, Optional
from urllib.parse import urlparse from urllib.parse import urlparse
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
@ -112,7 +112,7 @@ class ScopeMapping(PropertyMapping):
return "ak-property-mapping-scope-form" return "ak-property-mapping-scope-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.oauth2.api.scope import ScopeMappingSerializer from authentik.providers.oauth2.api.scope import ScopeMappingSerializer
return ScopeMappingSerializer return ScopeMappingSerializer
@ -267,7 +267,7 @@ class OAuth2Provider(Provider):
return "ak-provider-oauth2-form" return "ak-provider-oauth2-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
return OAuth2ProviderSerializer return OAuth2ProviderSerializer

View File

@ -1,7 +1,7 @@
"""authentik proxy models""" """authentik proxy models"""
import string import string
from random import SystemRandom from random import SystemRandom
from typing import Iterable, Optional, Type, Union from typing import Iterable, Optional
from urllib.parse import urljoin from urllib.parse import urljoin
from django.db import models from django.db import models
@ -110,7 +110,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
return "ak-provider-proxy-form" return "ak-provider-proxy-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.proxy.api import ProxyProviderSerializer from authentik.providers.proxy.api import ProxyProviderSerializer
return ProxyProviderSerializer return ProxyProviderSerializer
@ -138,7 +138,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
def __str__(self): def __str__(self):
return f"Proxy Provider {self.name}" return f"Proxy Provider {self.name}"
def get_required_objects(self) -> Iterable[Union[models.Model, str]]: def get_required_objects(self) -> Iterable[models.Model | str]:
required_models = [self] required_models = [self]
if self.certificate is not None: if self.certificate is not None:
required_models.append(self.certificate) required_models.append(self.certificate)

View File

@ -1,5 +1,5 @@
"""authentik saml_idp Models""" """authentik saml_idp Models"""
from typing import Optional, Type from typing import Optional
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
@ -163,7 +163,7 @@ class SAMLProvider(Provider):
return None return None
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.saml.api import SAMLProviderSerializer from authentik.providers.saml.api import SAMLProviderSerializer
return SAMLProviderSerializer return SAMLProviderSerializer
@ -192,7 +192,7 @@ class SAMLPropertyMapping(PropertyMapping):
return "ak-property-mapping-saml-form" return "ak-property-mapping-saml-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.providers.saml.api import SAMLPropertyMappingSerializer from authentik.providers.saml.api import SAMLPropertyMappingSerializer
return SAMLPropertyMappingSerializer return SAMLPropertyMappingSerializer

View File

@ -1,7 +1,7 @@
"""SAML AuthNRequest Parser and dataclass""" """SAML AuthNRequest Parser and dataclass"""
from base64 import b64decode from base64 import b64decode
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, Union from typing import Optional
from urllib.parse import quote_plus from urllib.parse import quote_plus
import xmlsec import xmlsec
@ -54,9 +54,7 @@ class AuthNRequestParser:
def __init__(self, provider: SAMLProvider): def __init__(self, provider: SAMLProvider):
self.provider = provider self.provider = provider
def _parse_xml( def _parse_xml(self, decoded_xml: str | bytes, relay_state: Optional[str]) -> AuthNRequest:
self, decoded_xml: Union[str, bytes], relay_state: Optional[str]
) -> AuthNRequest:
root = ElementTree.fromstring(decoded_xml) root = ElementTree.fromstring(decoded_xml)
# http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf # http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf

View File

@ -1,6 +1,5 @@
"""authentik LDAP Models""" """authentik LDAP Models"""
from ssl import CERT_REQUIRED from ssl import CERT_REQUIRED
from typing import Type
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -101,7 +100,7 @@ class LDAPSource(Source):
return "ak-source-ldap-form" return "ak-source-ldap-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.sources.ldap.api import LDAPSourceSerializer from authentik.sources.ldap.api import LDAPSourceSerializer
return LDAPSourceSerializer return LDAPSourceSerializer
@ -157,7 +156,7 @@ class LDAPPropertyMapping(PropertyMapping):
return "ak-property-mapping-ldap-form" return "ak-property-mapping-ldap-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.sources.ldap.api import LDAPPropertyMappingSerializer from authentik.sources.ldap.api import LDAPPropertyMappingSerializer
return LDAPPropertyMappingSerializer return LDAPPropertyMappingSerializer

View File

@ -48,7 +48,7 @@ class OAuthSource(Source):
consumer_secret = models.TextField() consumer_secret = models.TextField()
@property @property
def type(self) -> Type["SourceType"]: def type(self) -> type["SourceType"]:
"""Return the provider instance for this source""" """Return the provider instance for this source"""
from authentik.sources.oauth.types.manager import MANAGER from authentik.sources.oauth.types.manager import MANAGER
@ -58,6 +58,7 @@ class OAuthSource(Source):
def component(self) -> str: def component(self) -> str:
return "ak-source-oauth-form" return "ak-source-oauth-form"
# we're using Type[] instead of type[] here since type[] interferes with the property above
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> Type[Serializer]:
from authentik.sources.oauth.api.source import OAuthSourceSerializer from authentik.sources.oauth.api.source import OAuthSourceSerializer

View File

@ -59,7 +59,7 @@ class SourceTypeManager:
"""Manager to hold all Source types.""" """Manager to hold all Source types."""
def __init__(self) -> None: def __init__(self) -> None:
self.__sources: list[Type[SourceType]] = [] self.__sources: list[type[SourceType]] = []
def type(self): def type(self):
"""Class decorator to register classes inline.""" """Class decorator to register classes inline."""

View File

@ -1,5 +1,5 @@
"""OAuth Base views""" """OAuth Base views"""
from typing import Optional, Type from typing import Optional
from django.http.request import HttpRequest from django.http.request import HttpRequest
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -18,7 +18,7 @@ class OAuthClientMixin:
request: HttpRequest # Set by View class request: HttpRequest # Set by View class
client_class: Optional[Type[BaseOAuthClient]] = None client_class: Optional[type[BaseOAuthClient]] = None
def get_client(self, source: OAuthSource, **kwargs) -> BaseOAuthClient: def get_client(self, source: OAuthSource, **kwargs) -> BaseOAuthClient:
"Get instance of the OAuth client for this source." "Get instance of the OAuth client for this source."

View File

@ -1,5 +1,4 @@
"""saml sp models""" """saml sp models"""
from typing import Type
from django.db import models from django.db import models
from django.http import HttpRequest from django.http import HttpRequest
@ -150,7 +149,7 @@ class SAMLSource(Source):
return "ak-source-saml-form" return "ak-source-saml-form"
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> type[Serializer]:
from authentik.sources.saml.api import SAMLSourceSerializer from authentik.sources.saml.api import SAMLSourceSerializer
return SAMLSourceSerializer return SAMLSourceSerializer

View File

@ -1,5 +1,5 @@
"""Duo stage""" """Duo stage"""
from typing import Optional, Type from typing import Optional
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import models from django.db import models
@ -28,7 +28,7 @@ class AuthenticatorDuoStage(ConfigurableStage, Stage):
return AuthenticatorDuoStageSerializer return AuthenticatorDuoStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_duo.stage import AuthenticatorDuoStageView from authentik.stages.authenticator_duo.stage import AuthenticatorDuoStageView
return AuthenticatorDuoStageView return AuthenticatorDuoStageView

View File

@ -1,5 +1,5 @@
"""OTP Time-based models""" """OTP Time-based models"""
from typing import Optional, Type from typing import Optional
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import models from django.db import models
@ -132,7 +132,7 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
return AuthenticatorSMSStageSerializer return AuthenticatorSMSStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_sms.stage import AuthenticatorSMSStageView from authentik.stages.authenticator_sms.stage import AuthenticatorSMSStageView
return AuthenticatorSMSStageView return AuthenticatorSMSStageView

View File

@ -1,5 +1,5 @@
"""Static Authenticator models""" """Static Authenticator models"""
from typing import Optional, Type from typing import Optional
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -22,7 +22,7 @@ class AuthenticatorStaticStage(ConfigurableStage, Stage):
return AuthenticatorStaticStageSerializer return AuthenticatorStaticStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView
return AuthenticatorStaticStageView return AuthenticatorStaticStageView

View File

@ -1,5 +1,5 @@
"""OTP Time-based models""" """OTP Time-based models"""
from typing import Optional, Type from typing import Optional
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -29,7 +29,7 @@ class AuthenticatorTOTPStage(ConfigurableStage, Stage):
return AuthenticatorTOTPStageSerializer return AuthenticatorTOTPStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_totp.stage import AuthenticatorTOTPStageView from authentik.stages.authenticator_totp.stage import AuthenticatorTOTPStageView
return AuthenticatorTOTPStageView return AuthenticatorTOTPStageView

View File

@ -1,5 +1,4 @@
"""Authenticator Validation Stage""" """Authenticator Validation Stage"""
from typing import Type
from django.contrib.postgres.fields.array import ArrayField from django.contrib.postgres.fields.array import ArrayField
from django.db import models from django.db import models
@ -67,7 +66,7 @@ class AuthenticatorValidateStage(Stage):
return AuthenticatorValidateStageSerializer return AuthenticatorValidateStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_validate.stage import AuthenticatorValidateStageView from authentik.stages.authenticator_validate.stage import AuthenticatorValidateStageView
return AuthenticatorValidateStageView return AuthenticatorValidateStageView

View File

@ -1,5 +1,5 @@
"""WebAuthn stage""" """WebAuthn stage"""
from typing import Optional, Type from typing import Optional
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import models from django.db import models
@ -46,7 +46,7 @@ class AuthenticateWebAuthnStage(ConfigurableStage, Stage):
return AuthenticateWebAuthnStageSerializer return AuthenticateWebAuthnStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.authenticator_webauthn.stage import AuthenticatorWebAuthnStageView from authentik.stages.authenticator_webauthn.stage import AuthenticatorWebAuthnStageView
return AuthenticatorWebAuthnStageView return AuthenticatorWebAuthnStageView

View File

@ -1,5 +1,4 @@
"""authentik captcha stage""" """authentik captcha stage"""
from typing import Type
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -26,7 +25,7 @@ class CaptchaStage(Stage):
return CaptchaStageSerializer return CaptchaStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.captcha.stage import CaptchaStageView from authentik.stages.captcha.stage import CaptchaStageView
return CaptchaStageView return CaptchaStageView

View File

@ -1,5 +1,4 @@
"""authentik consent stage""" """authentik consent stage"""
from typing import Type
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -39,7 +38,7 @@ class ConsentStage(Stage):
return ConsentStageSerializer return ConsentStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.consent.stage import ConsentStageView from authentik.stages.consent.stage import ConsentStageView
return ConsentStageView return ConsentStageView

View File

@ -1,5 +1,4 @@
"""deny stage models""" """deny stage models"""
from typing import Type
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
@ -18,7 +17,7 @@ class DenyStage(Stage):
return DenyStageSerializer return DenyStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.deny.stage import DenyStageView from authentik.stages.deny.stage import DenyStageView
return DenyStageView return DenyStageView

View File

@ -1,5 +1,4 @@
"""dummy stage models""" """dummy stage models"""
from typing import Type
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views import View from django.views import View
@ -20,7 +19,7 @@ class DummyStage(Stage):
return DummyStageSerializer return DummyStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.dummy.stage import DummyStageView from authentik.stages.dummy.stage import DummyStageView
return DummyStageView return DummyStageView

View File

@ -88,7 +88,7 @@ class EmailStage(Stage):
return EmailStageSerializer return EmailStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.email.stage import EmailStageView from authentik.stages.email.stage import EmailStageView
return EmailStageView return EmailStageView

View File

@ -1,5 +1,4 @@
"""identification stage models""" """identification stage models"""
from typing import Type
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.db import models from django.db import models
@ -99,7 +98,7 @@ class IdentificationStage(Stage):
return IdentificationStageSerializer return IdentificationStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.identification.stage import IdentificationStageView from authentik.stages.identification.stage import IdentificationStageView
return IdentificationStageView return IdentificationStageView

View File

@ -1,5 +1,4 @@
"""invitation stage models""" """invitation stage models"""
from typing import Type
from uuid import uuid4 from uuid import uuid4
from django.db import models from django.db import models
@ -33,7 +32,7 @@ class InvitationStage(Stage):
return InvitationStageSerializer return InvitationStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.invitation.stage import InvitationStageView from authentik.stages.invitation.stage import InvitationStageView
return InvitationStageView return InvitationStageView

View File

@ -1,5 +1,5 @@
"""password stage models""" """password stage models"""
from typing import Optional, Type from typing import Optional
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.db import models from django.db import models
@ -54,7 +54,7 @@ class PasswordStage(ConfigurableStage, Stage):
return PasswordStageSerializer return PasswordStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.password.stage import PasswordStageView from authentik.stages.password.stage import PasswordStageView
return PasswordStageView return PasswordStageView

View File

@ -1,5 +1,5 @@
"""prompt models""" """prompt models"""
from typing import Any, Optional, Type from typing import Any, Optional
from uuid import uuid4 from uuid import uuid4
from django.db import models from django.db import models
@ -146,7 +146,7 @@ class PromptStage(Stage):
return PromptStageSerializer return PromptStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.prompt.stage import PromptStageView from authentik.stages.prompt.stage import PromptStageView
return PromptStageView return PromptStageView

View File

@ -1,5 +1,4 @@
"""delete stage models""" """delete stage models"""
from typing import Type
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
@ -19,7 +18,7 @@ class UserDeleteStage(Stage):
return UserDeleteStageSerializer return UserDeleteStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.user_delete.stage import UserDeleteStageView from authentik.stages.user_delete.stage import UserDeleteStageView
return UserDeleteStageView return UserDeleteStageView

View File

@ -1,5 +1,4 @@
"""login stage models""" """login stage models"""
from typing import Type
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -30,7 +29,7 @@ class UserLoginStage(Stage):
return UserLoginStageSerializer return UserLoginStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.user_login.stage import UserLoginStageView from authentik.stages.user_login.stage import UserLoginStageView
return UserLoginStageView return UserLoginStageView

View File

@ -1,5 +1,4 @@
"""logout stage models""" """logout stage models"""
from typing import Type
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
@ -18,7 +17,7 @@ class UserLogoutStage(Stage):
return UserLogoutStageSerializer return UserLogoutStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.user_logout.stage import UserLogoutStageView from authentik.stages.user_logout.stage import UserLogoutStageView
return UserLogoutStageView return UserLogoutStageView

View File

@ -1,5 +1,4 @@
"""write stage models""" """write stage models"""
from typing import Type
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -34,7 +33,7 @@ class UserWriteStage(Stage):
return UserWriteStageSerializer return UserWriteStageSerializer
@property @property
def type(self) -> Type[View]: def type(self) -> type[View]:
from authentik.stages.user_write.stage import UserWriteStageView from authentik.stages.user_write.stage import UserWriteStageView
return UserWriteStageView return UserWriteStageView