authentik.lib.utils.reflection

authentik lib reflection utilities

 1"""authentik lib reflection utilities"""
 2
 3import os
 4from importlib import import_module
 5from pathlib import Path
 6from tempfile import gettempdir
 7
 8from django.conf import settings
 9from django.utils.module_loading import import_string
10
11from authentik.lib.config import CONFIG
12
13SERVICE_HOST_ENV_NAME = "KUBERNETES_SERVICE_HOST"
14
15
16def all_subclasses[T: type](cls: T, sort=True) -> list[T] | set[T]:
17    """Recursively return all subclassess of cls"""
18    classes = set(cls.__subclasses__()).union(
19        [s for c in cls.__subclasses__() for s in all_subclasses(c, sort=sort)]
20    )
21    # Check if we're in debug mode, if not exclude classes which have `__debug_only__`
22    if not settings.DEBUG:
23        # Filter class out when __debug_only__ is not False
24        classes = [x for x in classes if not getattr(x, "__debug_only__", False)]
25        # classes = filter(lambda x: not getattr(x, "__debug_only__", False), classes)
26    if sort:
27        return sorted(classes, key=lambda x: x.__name__)
28    return classes
29
30
31def class_to_path(cls: type) -> str:
32    """Turn Class (Class or instance) into module path"""
33    return f"{cls.__module__}.{cls.__name__}"
34
35
36def path_to_class(path: str = "") -> type:
37    """Import module and return class"""
38    parts = path.split(".")
39    package = ".".join(parts[:-1])
40    _class = getattr(import_module(package), parts[-1])
41    return _class
42
43
44def get_apps():
45    """Get list of all authentik apps"""
46    from django.apps.registry import apps
47
48    for _app in apps.get_app_configs():
49        if _app.name.startswith("authentik"):
50            yield _app
51
52
53def get_env() -> str:
54    """Get environment in which authentik is currently running"""
55    if "CI" in os.environ:
56        return "ci"
57    if CONFIG.get_bool("debug"):
58        return "dev"
59    if SERVICE_HOST_ENV_NAME in os.environ:
60        return "kubernetes"
61    if (Path(gettempdir()) / "authentik-mode").exists():
62        return "compose"
63    if "AK_APPLIANCE" in os.environ:
64        return os.environ["AK_APPLIANCE"]
65    return "custom"
66
67
68class _dummy:
69    """Dummy class used for conditional inheritance as a placeholder when the specified
70    class is not available"""
71
72
73def ConditionalInheritance(path: str):
74    """Conditionally inherit from a class, intended for things like authentik.enterprise,
75    without which authentik should still be able to run"""
76    try:
77        cls = import_string(path)
78        return cls
79    except ModuleNotFoundError:
80        return _dummy
SERVICE_HOST_ENV_NAME = 'KUBERNETES_SERVICE_HOST'
def all_subclasses(cls: T, sort=True) -> list[T] | set[T]:
17def all_subclasses[T: type](cls: T, sort=True) -> list[T] | set[T]:
18    """Recursively return all subclassess of cls"""
19    classes = set(cls.__subclasses__()).union(
20        [s for c in cls.__subclasses__() for s in all_subclasses(c, sort=sort)]
21    )
22    # Check if we're in debug mode, if not exclude classes which have `__debug_only__`
23    if not settings.DEBUG:
24        # Filter class out when __debug_only__ is not False
25        classes = [x for x in classes if not getattr(x, "__debug_only__", False)]
26        # classes = filter(lambda x: not getattr(x, "__debug_only__", False), classes)
27    if sort:
28        return sorted(classes, key=lambda x: x.__name__)
29    return classes

Recursively return all subclassess of cls

def class_to_path(cls: type) -> str:
32def class_to_path(cls: type) -> str:
33    """Turn Class (Class or instance) into module path"""
34    return f"{cls.__module__}.{cls.__name__}"

Turn Class (Class or instance) into module path

def path_to_class(path: str = '') -> type:
37def path_to_class(path: str = "") -> type:
38    """Import module and return class"""
39    parts = path.split(".")
40    package = ".".join(parts[:-1])
41    _class = getattr(import_module(package), parts[-1])
42    return _class

Import module and return class

def get_apps():
45def get_apps():
46    """Get list of all authentik apps"""
47    from django.apps.registry import apps
48
49    for _app in apps.get_app_configs():
50        if _app.name.startswith("authentik"):
51            yield _app

Get list of all authentik apps

def get_env() -> str:
54def get_env() -> str:
55    """Get environment in which authentik is currently running"""
56    if "CI" in os.environ:
57        return "ci"
58    if CONFIG.get_bool("debug"):
59        return "dev"
60    if SERVICE_HOST_ENV_NAME in os.environ:
61        return "kubernetes"
62    if (Path(gettempdir()) / "authentik-mode").exists():
63        return "compose"
64    if "AK_APPLIANCE" in os.environ:
65        return os.environ["AK_APPLIANCE"]
66    return "custom"

Get environment in which authentik is currently running

def ConditionalInheritance(path: str):
74def ConditionalInheritance(path: str):
75    """Conditionally inherit from a class, intended for things like authentik.enterprise,
76    without which authentik should still be able to run"""
77    try:
78        cls = import_string(path)
79        return cls
80    except ModuleNotFoundError:
81        return _dummy

Conditionally inherit from a class, intended for things like authentik.enterprise, without which authentik should still be able to run