Compare commits

..

1 Commits

Author SHA1 Message Date
406d18ead6 Update beta.mdx
Added explanation of what our next versions are, clarified step to run upgrade commands, linked to Release Notes page.

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
2023-05-11 18:04:26 -05:00
147 changed files with 3897 additions and 13075 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2023.5.2
current_version = 2023.4.1
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)

View File

@ -112,7 +112,7 @@ jobs:
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.7.0
uses: helm/kind-action@v1.5.0
- name: run integration
run: |
poetry run coverage run manage.py test tests/integration

View File

@ -1,11 +1,10 @@
{
"recommendations": [
"EditorConfig.EditorConfig",
"bashmish.es6-string-css",
"bpruitt-goddard.mermaid-markdown-syntax-highlighting",
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"esbenp.prettier-vscode",
"github.vscode-github-actions",
"golang.go",
"Gruntfuggly.todo-tree",
"mechatroner.rainbow-csv",
@ -16,6 +15,6 @@
"ms-python.vscode-pylance",
"redhat.vscode-yaml",
"Tobermory.es6-string-html",
"unifiedjs.vscode-mdx",
"unifiedjs.vscode-mdx"
]
}

View File

@ -48,10 +48,5 @@
"ignoreCase": false
}
],
"go.testFlags": [
"-count=1"
],
"github-actions.workflows.pinned.workflows": [
".github/workflows/ci-main.yml"
]
"go.testFlags": ["-count=1"]
}

View File

@ -7,7 +7,7 @@ COPY ./SECURITY.md /work/
ENV NODE_ENV=production
WORKDIR /work/website
RUN npm ci --include=dev && npm run build-docs-only
RUN npm ci && npm run build-docs-only
# Stage 2: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
@ -17,7 +17,7 @@ COPY ./website /work/website/
ENV NODE_ENV=production
WORKDIR /work/web
RUN npm ci --include=dev && npm run build
RUN npm ci && npm run build
# Stage 3: Poetry to requirements.txt export
FROM docker.io/python:3.11.3-slim-bullseye AS poetry-locker

View File

@ -6,8 +6,8 @@ Authentik takes security very seriously. We follow the rules of [responsible dis
| Version | Supported |
| --------- | ------------------ |
| 2023.4.x | :white_check_mark: |
| 2023.5.x | :white_check_mark: |
| 2023.2.x | :white_check_mark: |
| 2023.3.x | :white_check_mark: |
## Reporting a Vulnerability

View File

@ -2,7 +2,7 @@
from os import environ
from typing import Optional
__version__ = "2023.5.2"
__version__ = "2023.4.1"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -1,5 +1,5 @@
"""core Configs API"""
from pathlib import Path
from os import path
from django.conf import settings
from django.db import models
@ -63,7 +63,7 @@ class ConfigView(APIView):
"""Get all capabilities this server instance supports"""
caps = []
deb_test = settings.DEBUG or settings.TEST
if Path(settings.MEDIA_ROOT).is_mount() or deb_test:
if path.ismount(settings.MEDIA_ROOT) or deb_test:
caps.append(Capabilities.CAN_SAVE_MEDIA)
if GEOIP_READER.enabled:
caps.append(Capabilities.CAN_GEO_IP)

View File

@ -11,7 +11,7 @@ from rest_framework.serializers import ListSerializer, ModelSerializer
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
from authentik.blueprints.models import BlueprintInstance
from authentik.blueprints.models import BlueprintInstance, BlueprintRetrievalFailed
from authentik.blueprints.v1.importer import Importer
from authentik.blueprints.v1.tasks import apply_blueprint, blueprints_find_dict
from authentik.core.api.used_by import UsedByMixin
@ -35,12 +35,11 @@ class BlueprintInstanceSerializer(ModelSerializer):
"""Info about a single blueprint instance file"""
def validate_path(self, path: str) -> str:
"""Ensure the path (if set) specified is retrievable"""
if path == "":
return path
files: list[dict] = blueprints_find_dict.delay().get()
if path not in [file["path"] for file in files]:
raise ValidationError(_("Blueprint file does not exist"))
"""Ensure the path specified is retrievable"""
try:
BlueprintInstance(path=path).retrieve()
except BlueprintRetrievalFailed as exc:
raise ValidationError(exc) from exc
return path
def validate_content(self, content: str) -> str:

View File

@ -10,7 +10,7 @@ from rest_framework.serializers import Serializer
from structlog.stdlib import get_logger
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT, is_model_allowed
from authentik.blueprints.v1.meta.registry import BaseMetaModel, registry
from authentik.blueprints.v1.meta.registry import registry
from authentik.lib.models import SerializerModel
LOGGER = get_logger()
@ -74,18 +74,14 @@ class Command(BaseCommand):
def build(self):
"""Build all models into the schema"""
for model in registry.get_models():
if issubclass(model, BaseMetaModel):
serializer_class = model.serializer()
else:
if model._meta.abstract:
continue
if not is_model_allowed(model):
continue
model_instance: Model = model()
if not isinstance(model_instance, SerializerModel):
continue
serializer_class = model_instance.serializer
serializer = serializer_class(
if model._meta.abstract:
continue
if not is_model_allowed(model):
continue
model_instance: Model = model()
if not isinstance(model_instance, SerializerModel):
continue
serializer = model_instance.serializer(
context={
SERIALIZER_CONTEXT_BLUEPRINT: False,
}

View File

@ -45,7 +45,7 @@ def check_blueprint_v1_file(BlueprintInstance: type, path: Path):
enabled=True,
managed_models=[],
last_applied_hash="",
metadata=metadata or {},
metadata=metadata,
)
instance.save()

View File

@ -11,37 +11,31 @@ metadata:
entries:
- model: authentik_core.token
identifiers:
identifier: "%(uid)s-token"
identifier: %(uid)s-token
attrs:
key: "%(uid)s"
user: "%(user)s"
key: %(uid)s
user: %(user)s
intent: api
- model: authentik_core.application
identifiers:
slug: "%(uid)s-app"
slug: %(uid)s-app
attrs:
name: "%(uid)s-app"
name: %(uid)s-app
icon: https://goauthentik.io/img/icon.png
- model: authentik_sources_oauth.oauthsource
identifiers:
slug: "%(uid)s-source"
slug: %(uid)s-source
attrs:
name: "%(uid)s-source"
name: %(uid)s-source
provider_type: azuread
consumer_key: "%(uid)s"
consumer_secret: "%(uid)s"
consumer_key: %(uid)s
consumer_secret: %(uid)s
icon: https://goauthentik.io/img/icon.png
- model: authentik_flows.flow
identifiers:
slug: "%(uid)s-flow"
slug: %(uid)s-flow
attrs:
name: "%(uid)s-flow"
title: "%(uid)s-flow"
name: %(uid)s-flow
title: %(uid)s-flow
designation: authentication
background: https://goauthentik.io/img/icon.png
- model: authentik_core.user
identifiers:
username: "%(uid)s"
attrs:
name: "%(uid)s"
password: "%(uid)s"

View File

@ -32,29 +32,6 @@ class TestBlueprintOCI(TransactionTestCase):
"foo",
)
def test_successful_port(self):
"""Successful retrieval with custom port"""
with Mocker() as mocker:
mocker.get(
"https://ghcr.io:1234/v2/goauthentik/blueprints/test/manifests/latest",
json={
"layers": [
{
"mediaType": OCI_MEDIA_TYPE,
"digest": "foo",
}
]
},
)
mocker.get("https://ghcr.io:1234/v2/goauthentik/blueprints/test/blobs/foo", text="foo")
self.assertEqual(
BlueprintInstance(
path="oci://ghcr.io:1234/goauthentik/blueprints/test:latest"
).retrieve(),
"foo",
)
def test_manifests_error(self):
"""Test manifests request erroring"""
with Mocker() as mocker:

View File

@ -2,7 +2,7 @@
from django.test import TransactionTestCase
from authentik.blueprints.v1.importer import Importer
from authentik.core.models import Application, Token, User
from authentik.core.models import Application, Token
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
@ -45,9 +45,3 @@ class TestBlueprintsV1ConditionalFields(TransactionTestCase):
flow = Flow.objects.filter(slug=f"{self.uid}-flow").first()
self.assertIsNotNone(flow)
self.assertEqual(flow.background, "https://goauthentik.io/img/icon.png")
def test_user(self):
"""Test user"""
user: User = User.objects.filter(username=self.uid).first()
self.assertIsNotNone(user)
self.assertTrue(user.check_password(self.uid))

View File

@ -39,16 +39,11 @@ class BlueprintOCIClient:
self.logger = get_logger().bind(url=self.sanitized_url)
self.ref = "latest"
# Remove the leading slash of the path to convert it to an image name
path = self.url.path[1:]
if ":" in path:
# if there's a colon in the path, use everything after it as a ref
if ":" in self.url.path:
path, _, self.ref = path.partition(":")
base_url = f"https://{self.url.hostname}"
if self.url.port:
base_url += f":{self.url.port}"
self.client = NewClient(
base_url,
f"https://{self.url.hostname}",
WithUserAgent(authentik_user_agent()),
WithUsernamePassword(self.url.username, self.url.password),
WithDefaultName(path),

View File

@ -184,9 +184,9 @@ def apply_blueprint(self: MonitoredTask, instance_pk: str):
instance: Optional[BlueprintInstance] = None
try:
instance: BlueprintInstance = BlueprintInstance.objects.filter(pk=instance_pk).first()
self.set_uid(slugify(instance.name))
if not instance or not instance.enabled:
return
self.set_uid(slugify(instance.name))
blueprint_content = instance.retrieve()
file_hash = sha512(blueprint_content.encode()).hexdigest()
importer = Importer(blueprint_content, instance.context)

View File

@ -33,7 +33,7 @@ class TokenSerializer(ManagedSerializer, ModelSerializer):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
if SERIALIZER_CONTEXT_BLUEPRINT in self.context:
self.fields["key"] = CharField(required=False)
self.fields["key"] = CharField()
def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
"""Ensure only API or App password tokens are created."""

View File

@ -51,7 +51,6 @@ from structlog.stdlib import get_logger
from authentik.admin.api.metrics import CoordinateSerializer
from authentik.api.decorators import permission_required
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import LinkSerializer, PassiveSerializer, is_dict
from authentik.core.middleware import (
@ -107,36 +106,12 @@ class UserSerializer(ModelSerializer):
avatar = CharField(read_only=True)
attributes = JSONField(validators=[is_dict], required=False)
groups = PrimaryKeyRelatedField(
allow_empty=True, many=True, source="ak_groups", queryset=Group.objects.all(), default=list
allow_empty=True, many=True, source="ak_groups", queryset=Group.objects.all()
)
groups_obj = ListSerializer(child=UserGroupSerializer(), read_only=True, source="ak_groups")
uid = CharField(read_only=True)
username = CharField(max_length=150, validators=[UniqueValidator(queryset=User.objects.all())])
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if SERIALIZER_CONTEXT_BLUEPRINT in self.context:
self.fields["password"] = CharField(required=False)
def create(self, validated_data: dict) -> User:
"""If this serializer is used in the blueprint context, we allow for
directly setting a password. However should be done via the `set_password`
method instead of directly setting it like rest_framework."""
instance: User = super().create(validated_data)
if SERIALIZER_CONTEXT_BLUEPRINT in self.context and "password" in validated_data:
instance.set_password(validated_data["password"])
instance.save()
return instance
def update(self, instance: User, validated_data: dict) -> User:
"""Same as `create` above, set the password directly if we're in a blueprint
context"""
instance = super().update(instance, validated_data)
if SERIALIZER_CONTEXT_BLUEPRINT in self.context and "password" in validated_data:
instance.set_password(validated_data["password"])
instance.save()
return instance
def validate_path(self, path: str) -> str:
"""Validate path"""
if path[:1] == "/" or path[-1] == "/":

View File

@ -5,6 +5,7 @@ from typing import Any, Optional
from uuid import uuid4
from deepmerge import always_merger
from django.conf import settings
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager as DjangoUserManager
@ -32,7 +33,6 @@ from authentik.lib.models import (
)
from authentik.lib.utils.http import get_client_ip
from authentik.policies.models import PolicyBindingModel
from authentik.root.install_id import get_install_id
LOGGER = get_logger()
USER_ATTRIBUTE_DEBUG = "goauthentik.io/user/debug"
@ -217,7 +217,7 @@ class User(SerializerModel, GuardianUserMixin, AbstractUser):
@property
def uid(self) -> str:
"""Generate a globally unique UID, based on the user ID and the hashed secret key"""
return sha256(f"{self.id}-{get_install_id()}".encode("ascii")).hexdigest()
return sha256(f"{self.id}-{settings.SECRET_KEY}".encode("ascii")).hexdigest()
def locale(self, request: Optional[HttpRequest] = None) -> str:
"""Get the locale the user has configured"""

View File

@ -28,7 +28,7 @@ from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSI
from authentik.lib.utils.urls import redirect_with_qs
from authentik.lib.views import bad_request_message
from authentik.policies.denied import AccessDeniedResponse
from authentik.policies.utils import delete_none_values
from authentik.policies.utils import delete_none_keys
from authentik.stages.password import BACKEND_INBUILT
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
@ -329,7 +329,7 @@ class SourceFlowManager:
)
],
**{
PLAN_CONTEXT_PROMPT: delete_none_values(self.enroll_info),
PLAN_CONTEXT_PROMPT: delete_none_keys(self.enroll_info),
PLAN_CONTEXT_USER_PATH: self.source.get_user_path(),
},
)

View File

@ -4,8 +4,8 @@
{% block head %}
<script src="{% static 'dist/user/UserInterface.js' %}?version={{ version }}" type="module"></script>
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
<link rel="icon" href="{{ tenant.branding_favicon }}">
<link rel="shortcut icon" href="{{ tenant.branding_favicon }}">
{% include "base/header_js.html" %}

View File

@ -7,6 +7,7 @@ from smtplib import SMTPException
from typing import TYPE_CHECKING, Optional
from uuid import uuid4
from django.conf import settings
from django.db import models
from django.db.models import Count, ExpressionWrapper, F
from django.db.models.fields import DurationField
@ -206,7 +207,9 @@ class Event(SerializerModel, ExpiringModel):
self.user = get_user(user)
return self
def from_http(self, request: HttpRequest, user: Optional[User] = None) -> "Event":
def from_http(
self, request: HttpRequest, user: Optional[settings.AUTH_USER_MODEL] = None
) -> "Event":
"""Add data from a Django-HttpRequest, allowing the creation of
Events independently from requests.
`user` arguments optionally overrides user from requests."""

View File

@ -87,9 +87,9 @@ class TaskInfo:
except TypeError:
duration = 0
GAUGE_TASKS.labels(
task_name=self.task_name.split(":")[0],
task_name=self.task_name,
task_uid=self.result.uid or "",
status=self.result.status.value,
status=self.result.status,
).set(duration)
def save(self, timeout_hours=6):

View File

@ -2,7 +2,6 @@
import re
from copy import copy
from dataclasses import asdict, is_dataclass
from enum import Enum
from pathlib import Path
from types import GeneratorType
from typing import Any, Optional
@ -127,8 +126,6 @@ def sanitize_item(value: Any) -> Any:
return str(value)
if isinstance(value, YAMLTag):
return str(value)
if isinstance(value, Enum):
return value.value
if isinstance(value, type):
return {
"type": value.__name__,

View File

@ -23,7 +23,6 @@ from authentik.flows.api.bindings import FlowStageBindingSerializer
from authentik.flows.models import Flow
from authentik.flows.planner import FlowPlan
from authentik.flows.views.executor import SESSION_KEY_HISTORY, SESSION_KEY_PLAN
from authentik.root.install_id import get_install_id
class FlowInspectorPlanSerializer(PassiveSerializer):
@ -52,7 +51,7 @@ class FlowInspectorPlanSerializer(PassiveSerializer):
"""Get a unique session ID"""
request: Request = self.context["request"]
return sha256(
f"{request._request.session.session_key}-{get_install_id()}".encode("ascii")
f"{request._request.session.session_key}-{settings.SECRET_KEY}".encode("ascii")
).hexdigest()

View File

@ -5,7 +5,6 @@ from contextlib import contextmanager
from glob import glob
from json import dumps, loads
from json.decoder import JSONDecodeError
from pathlib import Path
from sys import argv, stderr
from time import time
from typing import Any
@ -43,25 +42,22 @@ class ConfigLoader:
def __init__(self):
super().__init__()
self.__config = {}
base_dir = Path(__file__).parent.joinpath(Path("../..")).resolve()
for _path in SEARCH_PATHS:
path = Path(_path)
base_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../.."))
for path in SEARCH_PATHS:
# Check if path is relative, and if so join with base_dir
if not path.is_absolute():
path = base_dir / path
if path.is_file() and path.exists():
if not os.path.isabs(path):
path = os.path.join(base_dir, path)
if os.path.isfile(path) and os.path.exists(path):
# Path is an existing file, so we just read it and update our config with it
self.update_from_file(path)
elif path.is_dir() and path.exists():
elif os.path.isdir(path) and os.path.exists(path):
# Path is an existing dir, so we try to read the env config from it
env_paths = [
path / Path(ENVIRONMENT + ".yml"),
path / Path(ENVIRONMENT + ".env.yml"),
path / Path(ENVIRONMENT + ".yaml"),
path / Path(ENVIRONMENT + ".env.yaml"),
os.path.join(path, ENVIRONMENT + ".yml"),
os.path.join(path, ENVIRONMENT + ".env.yml"),
]
for env_file in env_paths:
if env_file.is_file() and env_file.exists():
if os.path.isfile(env_file) and os.path.exists(env_file):
# Update config with env file
self.update_from_file(env_file)
self.update_from_env()
@ -103,13 +99,13 @@ class ConfigLoader:
value = url.query
return value
def update_from_file(self, path: Path):
def update_from_file(self, path: str):
"""Update config from file contents"""
try:
with open(path, encoding="utf8") as file:
try:
self.update(self.__config, yaml.safe_load(file))
self.log("debug", "Loaded config", file=str(path))
self.log("debug", "Loaded config", file=path)
self.loaded_file.append(path)
except yaml.YAMLError as exc:
raise ImproperlyConfigured from exc

View File

@ -140,21 +140,19 @@ class BaseEvaluator:
def expr_event_create(self, action: str, **kwargs):
"""Create event with supplied data and try to extract as much relevant data
from the context"""
context = self._context.copy()
# If the result was a complex variable, we don't want to re-use it
context.pop("result", None)
context.pop("handler", None)
event_kwargs = context
event_kwargs.update(kwargs)
self._context.pop("result", None)
self._context.pop("handler", None)
kwargs["context"] = self._context
event = Event.new(
action,
app=self._filename,
**event_kwargs,
**kwargs,
)
if "request" in context and isinstance(context["request"], PolicyRequest):
policy_request: PolicyRequest = context["request"]
if "request" in self._context and isinstance(self._context["request"], PolicyRequest):
policy_request: PolicyRequest = self._context["request"]
if policy_request.http_request:
event.from_http(policy_request.http_request)
event.from_http(policy_request)
return
event.save()

View File

@ -19,15 +19,7 @@ def fallback_names(app: str, model: str, field: str):
if value not in seen_names:
seen_names.append(value)
continue
separator = "_"
suffix_index = 2
while (
klass.objects.using(db_alias)
.filter(**{field: f"{value}{separator}{suffix_index}"})
.exists()
):
suffix_index += 1
new_value = f"{value}{separator}{suffix_index}"
new_value = value + "_2"
setattr(obj, field, new_value)
obj.save()

View File

@ -2,41 +2,28 @@
from django.test import TestCase
from authentik.core.tests.utils import create_test_admin_user
from authentik.events.models import Event
from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.lib.generators import generate_id
class TestEvaluator(TestCase):
"""Test Evaluator base functions"""
def test_expr_regex_match(self):
def test_regex_match(self):
"""Test expr_regex_match"""
self.assertFalse(BaseEvaluator.expr_regex_match("foo", "bar"))
self.assertTrue(BaseEvaluator.expr_regex_match("foo", "foo"))
def test_expr_regex_replace(self):
def test_regex_replace(self):
"""Test expr_regex_replace"""
self.assertEqual(BaseEvaluator.expr_regex_replace("foo", "o", "a"), "faa")
def test_expr_user_by(self):
def test_user_by(self):
"""Test expr_user_by"""
user = create_test_admin_user()
self.assertIsNotNone(BaseEvaluator.expr_user_by(username=user.username))
self.assertIsNone(BaseEvaluator.expr_user_by(username="bar"))
self.assertIsNone(BaseEvaluator.expr_user_by(foo="bar"))
def test_expr_is_group_member(self):
def test_is_group_member(self):
"""Test expr_is_group_member"""
self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test"))
def test_expr_event_create(self):
"""Test expr_event_create"""
evaluator = BaseEvaluator(generate_id())
evaluator._context = {
"foo": "bar",
}
evaluator.evaluate("ak_create_event('foo', bar='baz')")
event = Event.objects.filter(action="custom_foo").first()
self.assertIsNotNone(event)
self.assertEqual(event.context, {"bar": "baz", "foo": "bar"})

View File

@ -42,15 +42,12 @@ from authentik.providers.ldap.controllers.docker import LDAPDockerController
from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
from authentik.providers.proxy.controllers.docker import ProxyDockerController
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
from authentik.providers.radius.controllers.docker import RadiusDockerController
from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
from authentik.root.celery import CELERY_APP
LOGGER = get_logger()
CACHE_KEY_OUTPOST_DOWN = "goauthentik.io/outposts/teardown/%s"
# pylint: disable=too-many-return-statements
def controller_for_outpost(outpost: Outpost) -> Optional[type[BaseController]]:
"""Get a controller for the outpost, when a service connection is defined"""
if not outpost.service_connection:
@ -66,11 +63,6 @@ def controller_for_outpost(outpost: Outpost) -> Optional[type[BaseController]]:
return LDAPDockerController
if isinstance(service_connection, KubernetesServiceConnection):
return LDAPKubernetesController
if outpost.type == OutpostType.RADIUS:
if isinstance(service_connection, DockerServiceConnection):
return RadiusDockerController
if isinstance(service_connection, KubernetesServiceConnection):
return RadiusKubernetesController
return None

View File

@ -2,7 +2,7 @@
from typing import Any
def delete_none_values(dict_: dict[Any, Any]) -> dict[Any, Any]:
def delete_none_keys(dict_: dict[Any, Any]) -> dict[Any, Any]:
"""Remove any keys from `dict_` that are None."""
new_dict = {}
for key, value in dict_.items():

View File

@ -1,40 +1,185 @@
"""Kubernetes Traefik Middleware Reconciler"""
from dataclasses import asdict, dataclass, field
from typing import TYPE_CHECKING
from dacite.core import from_dict
from kubernetes.client import ApiextensionsV1Api, CustomObjectsApi
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
from authentik.outposts.controllers.kubernetes import KubernetesController
from authentik.providers.proxy.controllers.k8s.traefik_2 import Traefik2MiddlewareReconciler
from authentik.providers.proxy.controllers.k8s.traefik_3 import (
Traefik3MiddlewareReconciler,
TraefikMiddleware,
)
from authentik.outposts.controllers.k8s.triggers import NeedsUpdate
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
if TYPE_CHECKING:
from authentik.outposts.controllers.kubernetes import KubernetesController
class TraefikMiddlewareReconciler(KubernetesObjectReconciler):
@dataclass
class TraefikMiddlewareSpecForwardAuth:
"""traefik middleware forwardAuth spec"""
address: str
# pylint: disable=invalid-name
authResponseHeadersRegex: str = field(default="")
# pylint: disable=invalid-name
authResponseHeaders: list[str] = field(default_factory=list)
# pylint: disable=invalid-name
trustForwardHeader: bool = field(default=True)
@dataclass
class TraefikMiddlewareSpec:
"""Traefik middleware spec"""
# pylint: disable=invalid-name
forwardAuth: TraefikMiddlewareSpecForwardAuth
@dataclass
class TraefikMiddlewareMetadata:
"""Traefik Middleware metadata"""
name: str
namespace: str
labels: dict = field(default_factory=dict)
@dataclass
class TraefikMiddleware:
"""Traefik Middleware"""
# pylint: disable=invalid-name
apiVersion: str
kind: str
metadata: TraefikMiddlewareMetadata
spec: TraefikMiddlewareSpec
CRD_NAME = "middlewares.traefik.containo.us"
CRD_GROUP = "traefik.containo.us"
CRD_VERSION = "v1alpha1"
CRD_PLURAL = "middlewares"
class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]):
"""Kubernetes Traefik Middleware Reconciler"""
def __init__(self, controller: "KubernetesController") -> None:
super().__init__(controller)
self.reconciler = Traefik3MiddlewareReconciler(controller)
if not self.reconciler.crd_exists():
self.reconciler = Traefik2MiddlewareReconciler(controller)
self.api_ex = ApiextensionsV1Api(controller.client)
self.api = CustomObjectsApi(controller.client)
@property
def noop(self) -> bool:
return self.reconciler.noop
if not ProxyProvider.objects.filter(
outpost__in=[self.controller.outpost],
mode__in=[ProxyMode.FORWARD_SINGLE, ProxyMode.FORWARD_DOMAIN],
).exists():
self.logger.debug("No providers with forward auth enabled.")
return True
if not self._crd_exists():
self.logger.debug("CRD doesn't exist")
return True
return False
def _crd_exists(self) -> bool:
"""Check if the traefik middleware exists"""
return bool(
len(
self.api_ex.list_custom_resource_definition(
field_selector=f"metadata.name={CRD_NAME}"
).items
)
)
def reconcile(self, current: TraefikMiddleware, reference: TraefikMiddleware):
return self.reconcile(current, reference)
super().reconcile(current, reference)
if current.spec.forwardAuth.address != reference.spec.forwardAuth.address:
raise NeedsUpdate()
if (
current.spec.forwardAuth.authResponseHeadersRegex
!= reference.spec.forwardAuth.authResponseHeadersRegex
):
raise NeedsUpdate()
# Ensure all of our headers are set, others can be added by the user.
if not set(current.spec.forwardAuth.authResponseHeaders).issubset(
reference.spec.forwardAuth.authResponseHeaders
):
raise NeedsUpdate()
def get_reference_object(self) -> TraefikMiddleware:
return self.get_reference_object()
"""Get deployment object for outpost"""
return TraefikMiddleware(
apiVersion=f"{CRD_GROUP}/{CRD_VERSION}",
kind="Middleware",
metadata=TraefikMiddlewareMetadata(
name=self.name,
namespace=self.namespace,
labels=self.get_object_meta().labels,
),
spec=TraefikMiddlewareSpec(
forwardAuth=TraefikMiddlewareSpecForwardAuth(
address=(
f"http://{self.name}.{self.namespace}:9000/"
"outpost.goauthentik.io/auth/traefik"
),
authResponseHeaders=[
"X-authentik-username",
"X-authentik-groups",
"X-authentik-email",
"X-authentik-name",
"X-authentik-uid",
"X-authentik-jwt",
"X-authentik-meta-jwks",
"X-authentik-meta-outpost",
"X-authentik-meta-provider",
"X-authentik-meta-app",
"X-authentik-meta-version",
],
authResponseHeadersRegex="",
trustForwardHeader=True,
)
),
)
def create(self, reference: TraefikMiddleware):
return self.create(reference)
return self.api.create_namespaced_custom_object(
group=CRD_GROUP,
version=CRD_VERSION,
plural=CRD_PLURAL,
namespace=self.namespace,
body=asdict(reference),
field_manager=FIELD_MANAGER,
)
def delete(self, reference: TraefikMiddleware):
return self.delete(reference)
return self.api.delete_namespaced_custom_object(
group=CRD_GROUP,
version=CRD_VERSION,
namespace=self.namespace,
plural=CRD_PLURAL,
name=self.name,
)
def retrieve(self) -> TraefikMiddleware:
return self.retrieve()
return from_dict(
TraefikMiddleware,
self.api.get_namespaced_custom_object(
group=CRD_GROUP,
version=CRD_VERSION,
namespace=self.namespace,
plural=CRD_PLURAL,
name=self.name,
),
)
def update(self, current: TraefikMiddleware, reference: TraefikMiddleware):
return self.update(current, reference)
return self.api.patch_namespaced_custom_object(
group=CRD_GROUP,
version=CRD_VERSION,
namespace=self.namespace,
plural=CRD_PLURAL,
name=self.name,
body=asdict(reference),
field_manager=FIELD_MANAGER,
)

View File

@ -1,18 +0,0 @@
"""Kubernetes Traefik Middleware Reconciler"""
from typing import TYPE_CHECKING
from authentik.providers.proxy.controllers.k8s.traefik_3 import Traefik3MiddlewareReconciler
if TYPE_CHECKING:
from authentik.outposts.controllers.kubernetes import KubernetesController
class Traefik2MiddlewareReconciler(Traefik3MiddlewareReconciler):
"""Kubernetes Traefik Middleware Reconciler"""
def __init__(self, controller: "KubernetesController") -> None:
super().__init__(controller)
self.crd_name = "middlewares.traefik.containo.us"
self.crd_group = "traefik.containo.us"
self.crd_version = "v1alpha1"
self.crd_plural = "middlewares"

View File

@ -1,183 +0,0 @@
"""Kubernetes Traefik Middleware Reconciler"""
from dataclasses import asdict, dataclass, field
from typing import TYPE_CHECKING
from dacite.core import from_dict
from kubernetes.client import ApiextensionsV1Api, CustomObjectsApi
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
from authentik.outposts.controllers.k8s.triggers import NeedsUpdate
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
if TYPE_CHECKING:
from authentik.outposts.controllers.kubernetes import KubernetesController
@dataclass
class TraefikMiddlewareSpecForwardAuth:
"""traefik middleware forwardAuth spec"""
address: str
# pylint: disable=invalid-name
authResponseHeadersRegex: str = field(default="")
# pylint: disable=invalid-name
authResponseHeaders: list[str] = field(default_factory=list)
# pylint: disable=invalid-name
trustForwardHeader: bool = field(default=True)
@dataclass
class TraefikMiddlewareSpec:
"""Traefik middleware spec"""
# pylint: disable=invalid-name
forwardAuth: TraefikMiddlewareSpecForwardAuth
@dataclass
class TraefikMiddlewareMetadata:
"""Traefik Middleware metadata"""
name: str
namespace: str
labels: dict = field(default_factory=dict)
@dataclass
class TraefikMiddleware:
"""Traefik Middleware"""
# pylint: disable=invalid-name
apiVersion: str
kind: str
metadata: TraefikMiddlewareMetadata
spec: TraefikMiddlewareSpec
class Traefik3MiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]):
"""Kubernetes Traefik Middleware Reconciler"""
def __init__(self, controller: "KubernetesController") -> None:
super().__init__(controller)
self.api_ex = ApiextensionsV1Api(controller.client)
self.api = CustomObjectsApi(controller.client)
self.crd_name = "middlewares.traefik.io"
self.crd_group = "traefik.io"
self.crd_version = "v1alpha1"
self.crd_plural = "middlewares"
@property
def noop(self) -> bool:
if not ProxyProvider.objects.filter(
outpost__in=[self.controller.outpost],
mode__in=[ProxyMode.FORWARD_SINGLE, ProxyMode.FORWARD_DOMAIN],
).exists():
self.logger.debug("No providers with forward auth enabled.")
return True
if not self.crd_exists():
self.logger.debug("CRD doesn't exist")
return True
return False
def crd_exists(self) -> bool:
"""Check if the traefik middleware exists"""
return bool(
len(
self.api_ex.list_custom_resource_definition(
field_selector=f"metadata.name={self.crd_name}"
).items
)
)
def reconcile(self, current: TraefikMiddleware, reference: TraefikMiddleware):
super().reconcile(current, reference)
if current.spec.forwardAuth.address != reference.spec.forwardAuth.address:
raise NeedsUpdate()
if (
current.spec.forwardAuth.authResponseHeadersRegex
!= reference.spec.forwardAuth.authResponseHeadersRegex
):
raise NeedsUpdate()
# Ensure all of our headers are set, others can be added by the user.
if not set(current.spec.forwardAuth.authResponseHeaders).issubset(
reference.spec.forwardAuth.authResponseHeaders
):
raise NeedsUpdate()
def get_reference_object(self) -> TraefikMiddleware:
"""Get deployment object for outpost"""
return TraefikMiddleware(
apiVersion=f"{self.crd_group}/{self.crd_version}",
kind="Middleware",
metadata=TraefikMiddlewareMetadata(
name=self.name,
namespace=self.namespace,
labels=self.get_object_meta().labels,
),
spec=TraefikMiddlewareSpec(
forwardAuth=TraefikMiddlewareSpecForwardAuth(
address=(
f"http://{self.name}.{self.namespace}:9000/"
"outpost.goauthentik.io/auth/traefik"
),
authResponseHeaders=[
"X-authentik-username",
"X-authentik-groups",
"X-authentik-email",
"X-authentik-name",
"X-authentik-uid",
"X-authentik-jwt",
"X-authentik-meta-jwks",
"X-authentik-meta-outpost",
"X-authentik-meta-provider",
"X-authentik-meta-app",
"X-authentik-meta-version",
],
authResponseHeadersRegex="",
trustForwardHeader=True,
)
),
)
def create(self, reference: TraefikMiddleware):
return self.api.create_namespaced_custom_object(
group=self.crd_group,
version=self.crd_version,
plural=self.crd_plural,
namespace=self.namespace,
body=asdict(reference),
field_manager=FIELD_MANAGER,
)
def delete(self, reference: TraefikMiddleware):
return self.api.delete_namespaced_custom_object(
group=self.crd_group,
version=self.crd_version,
plural=self.crd_plural,
namespace=self.namespace,
name=self.name,
)
def retrieve(self) -> TraefikMiddleware:
return from_dict(
TraefikMiddleware,
self.api.get_namespaced_custom_object(
group=self.crd_group,
version=self.crd_version,
plural=self.crd_plural,
namespace=self.namespace,
name=self.name,
),
)
def update(self, current: TraefikMiddleware, reference: TraefikMiddleware):
return self.api.patch_namespaced_custom_object(
group=self.crd_group,
version=self.crd_version,
plural=self.crd_plural,
namespace=self.namespace,
name=self.name,
body=asdict(reference),
field_manager=FIELD_MANAGER,
)

View File

@ -1,5 +1,5 @@
"""RadiusProvider API Views"""
from rest_framework.fields import CharField, ListField
from rest_framework.fields import CharField
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
@ -11,8 +11,6 @@ from authentik.providers.radius.models import RadiusProvider
class RadiusProviderSerializer(ProviderSerializer):
"""RadiusProvider Serializer"""
outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
class Meta:
model = RadiusProvider
fields = ProviderSerializer.Meta.fields + [
@ -20,7 +18,6 @@ class RadiusProviderSerializer(ProviderSerializer):
# Shared secret is not a write-only field, as
# an admin might have to view it
"shared_secret",
"outpost_set",
]
extra_kwargs = ProviderSerializer.Meta.extra_kwargs

View File

@ -90,7 +90,6 @@ class TestAuthNRequest(TestCase):
issuer="authentik",
pre_authentication_flow=create_test_flow(),
signing_kp=cert,
verification_kp=cert,
)
def test_signed_valid(self):

View File

@ -24,8 +24,8 @@ class SCIMProviderSerializer(ProviderSerializer):
"property_mappings",
"property_mappings_group",
"component",
"assigned_backchannel_application_slug",
"assigned_backchannel_application_name",
"assigned_application_slug",
"assigned_application_name",
"verbose_name",
"verbose_name_plural",
"meta_model_name",

View File

@ -51,7 +51,7 @@ class SCIMClient(Generic[T, SchemaType]):
},
)
except RequestException as exc:
raise SCIMRequestException(message="Failed to send request") from exc
raise SCIMRequestException(None) from exc
self.logger.debug("scim request", path=path, method=method, **kwargs)
if response.status_code >= 400:
if response.status_code == 404:

View File

@ -2,10 +2,10 @@
from typing import Optional
from pydantic import ValidationError
from pydanticscim.responses import SCIMError
from requests import Response
from authentik.lib.sentry import SentryIgnoredException
from authentik.providers.scim.clients.schema import SCIMError
class StopSync(SentryIgnoredException):
@ -16,8 +16,7 @@ class StopSync(SentryIgnoredException):
self.obj = obj
self.mapping = mapping
def detail(self) -> str:
"""Get human readable details of this error"""
def __str__(self) -> str:
msg = f"Error {str(self.exc)}, caused by {self.obj}"
if self.mapping:
@ -29,22 +28,19 @@ class SCIMRequestException(SentryIgnoredException):
"""Exception raised when an SCIM request fails"""
_response: Optional[Response]
_message: Optional[str]
def __init__(self, response: Optional[Response] = None, message: Optional[str] = None) -> None:
def __init__(self, response: Optional[Response] = None) -> None:
self._response = response
self._message = message
def detail(self) -> str:
"""Get human readable details of this error"""
def __str__(self) -> str:
if not self._response:
return self._message
return super().__str__()
try:
error = SCIMError.parse_raw(self._response.text)
return error.detail
except ValidationError:
pass
return self._message
return super().__str__()
class ResourceMissing(SCIMRequestException):

View File

@ -8,7 +8,7 @@ from authentik.core.exceptions import PropertyMappingExpressionException
from authentik.core.models import Group
from authentik.events.models import Event, EventAction
from authentik.lib.utils.errors import exception_to_string
from authentik.policies.utils import delete_none_values
from authentik.policies.utils import delete_none_keys
from authentik.providers.scim.clients.base import SCIMClient
from authentik.providers.scim.clients.exceptions import (
ResourceMissing,
@ -74,7 +74,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroupSchema]):
if not raw_scim_group:
raise StopSync(ValueError("No group mappings configured"), obj)
try:
scim_group = SCIMGroupSchema.parse_obj(delete_none_values(raw_scim_group))
scim_group = SCIMGroupSchema.parse_obj(delete_none_keys(raw_scim_group))
except ValidationError as exc:
raise StopSync(exc, obj) from exc
if not scim_group.externalId:
@ -130,8 +130,10 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroupSchema]):
scim_group.id,
PatchOperation(
op=PatchOp.replace,
path="displayName",
value=scim_group.displayName,
value={
"id": connection.id,
"displayName": group.name,
},
),
)

View File

@ -3,7 +3,6 @@ from typing import Optional
from pydanticscim.group import Group as BaseGroup
from pydanticscim.responses import PatchRequest as BasePatchRequest
from pydanticscim.responses import SCIMError as BaseSCIMError
from pydanticscim.service_provider import Bulk, ChangePassword, Filter, Patch
from pydanticscim.service_provider import (
ServiceProviderConfiguration as BaseServiceProviderConfiguration,
@ -53,9 +52,3 @@ class PatchRequest(BasePatchRequest):
"""PatchRequest which correctly sets schemas"""
schemas: tuple[str] = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
class SCIMError(BaseSCIMError):
"""SCIM error with optional status code"""
status: Optional[int]

View File

@ -6,7 +6,7 @@ from authentik.core.exceptions import PropertyMappingExpressionException
from authentik.core.models import User
from authentik.events.models import Event, EventAction
from authentik.lib.utils.errors import exception_to_string
from authentik.policies.utils import delete_none_values
from authentik.policies.utils import delete_none_keys
from authentik.providers.scim.clients.base import SCIMClient
from authentik.providers.scim.clients.exceptions import ResourceMissing, StopSync
from authentik.providers.scim.clients.schema import User as SCIMUserSchema
@ -64,7 +64,7 @@ class SCIMUserClient(SCIMClient[User, SCIMUserSchema]):
if not raw_scim_user:
raise StopSync(ValueError("No user mappings configured"), obj)
try:
scim_user = SCIMUserSchema.parse_obj(delete_none_values(raw_scim_user))
scim_user = SCIMUserSchema.parse_obj(delete_none_keys(raw_scim_user))
except ValidationError as exc:
raise StopSync(exc, obj) from exc
if not scim_user.externalId:

View File

@ -42,9 +42,7 @@ def scim_sync_all():
@CELERY_APP.task(bind=True, base=MonitoredTask)
def scim_sync(self: MonitoredTask, provider_pk: int) -> None:
"""Run SCIM full sync for provider"""
provider: SCIMProvider = SCIMProvider.objects.filter(
pk=provider_pk, backchannel_application__isnull=False
).first()
provider: SCIMProvider = SCIMProvider.objects.filter(pk=provider_pk).first()
if not provider:
return
self.set_uid(slugify(provider.name))
@ -89,10 +87,10 @@ def scim_sync_users(page: int, provider_pk: int):
LOGGER.warning("failed to sync user", exc=exc, user=user)
messages.append(
_(
"Failed to sync user %(user_name)s due to remote error: %(error)s"
"Failed to sync user due to remote error %(name)s: %(error)s"
% {
"user_name": user.username,
"error": exc.detail(),
"name": user.username,
"error": str(exc),
}
)
)
@ -102,7 +100,7 @@ def scim_sync_users(page: int, provider_pk: int):
_(
"Stopping sync due to error: %(error)s"
% {
"error": exc.detail(),
"error": str(exc),
}
)
)
@ -130,10 +128,10 @@ def scim_sync_group(page: int, provider_pk: int):
LOGGER.warning("failed to sync group", exc=exc, group=group)
messages.append(
_(
"Failed to sync group %(group_name)s due to remote error: %(error)s"
"Failed to sync group due to remote error %(name)s: %(error)s"
% {
"group_name": group.name,
"error": exc.detail(),
"name": group.name,
"error": str(exc),
}
)
)
@ -143,7 +141,7 @@ def scim_sync_group(page: int, provider_pk: int):
_(
"Stopping sync due to error: %(error)s"
% {
"error": exc.detail(),
"error": str(exc),
}
)
)

View File

@ -36,7 +36,6 @@ class SCIMMembershipTests(TestCase):
slug=generate_id(),
)
self.app.backchannel_providers.add(self.provider)
self.provider.save()
self.provider.property_mappings.set(
[SCIMMapping.objects.get(managed="goauthentik.io/providers/scim/user")]
)
@ -92,6 +91,7 @@ class SCIMMembershipTests(TestCase):
"active": True,
"externalId": user.uid,
"name": {"familyName": "", "formatted": "", "givenName": ""},
"photos": [],
"displayName": "",
"userName": user.username,
},
@ -177,6 +177,7 @@ class SCIMMembershipTests(TestCase):
"emails": [],
"externalId": user.uid,
"name": {"familyName": "", "formatted": "", "givenName": ""},
"photos": [],
"userName": user.username,
},
)

View File

@ -81,6 +81,7 @@ class SCIMUserTests(TestCase):
"givenName": uid,
},
"displayName": uid,
"photos": [],
"userName": uid,
},
)
@ -136,6 +137,7 @@ class SCIMUserTests(TestCase):
"formatted": uid,
"givenName": uid,
},
"photos": [],
"userName": uid,
},
)
@ -188,6 +190,7 @@ class SCIMUserTests(TestCase):
"givenName": uid,
},
"displayName": uid,
"photos": [],
"userName": uid,
},
)
@ -255,6 +258,7 @@ class SCIMUserTests(TestCase):
"givenName": uid,
},
"displayName": uid,
"photos": [],
"userName": uid,
},
)

View File

@ -1,41 +0,0 @@
"""install ID"""
from functools import lru_cache
from uuid import uuid4
from psycopg2 import connect
from authentik.lib.config import CONFIG
@lru_cache
def get_install_id() -> str:
"""Get install ID of this instance. The method is cached as the install ID is
not expected to change"""
from django.conf import settings
from django.db import connection
if settings.TEST:
return str(uuid4())
with connection.cursor() as cursor:
cursor.execute("SELECT id FROM authentik_install_id LIMIT 1;")
return cursor.fetchone()[0]
@lru_cache
def get_install_id_raw():
"""Get install_id without django loaded, this is required for the startup when we get
the install_id but django isn't loaded yet and we can't use the function above."""
conn = connect(
dbname=CONFIG.y("postgresql.name"),
user=CONFIG.y("postgresql.user"),
password=CONFIG.y("postgresql.password"),
host=CONFIG.y("postgresql.host"),
port=int(CONFIG.y("postgresql.port")),
sslmode=CONFIG.y("postgresql.sslmode"),
sslrootcert=CONFIG.y("postgresql.sslrootcert"),
sslcert=CONFIG.y("postgresql.sslcert"),
sslkey=CONFIG.y("postgresql.sslkey"),
)
cursor = conn.cursor()
cursor.execute("SELECT id FROM authentik_install_id LIMIT 1;")
return cursor.fetchone()[0]

View File

@ -1,5 +1,4 @@
"""Dynamically set SameSite depending if the upstream connection is TLS or not"""
from functools import lru_cache
from hashlib import sha512
from time import time
from timeit import default_timer
@ -17,16 +16,10 @@ from jwt import PyJWTError, decode, encode
from structlog.stdlib import get_logger
from authentik.lib.utils.http import get_client_ip
from authentik.root.install_id import get_install_id
LOGGER = get_logger("authentik.asgi")
ACR_AUTHENTIK_SESSION = "goauthentik.io/core/default"
@lru_cache
def get_signing_hash():
"""Get cookie JWT signing hash"""
return sha512(get_install_id().encode()).hexdigest()
SIGNING_HASH = sha512(settings.SECRET_KEY.encode()).hexdigest()
class SessionMiddleware(UpstreamSessionMiddleware):
@ -54,7 +47,7 @@ class SessionMiddleware(UpstreamSessionMiddleware):
# for testing setups, where the session is directly set
session_key = key if settings.TEST else None
try:
session_payload = decode(key, get_signing_hash(), algorithms=["HS256"])
session_payload = decode(key, SIGNING_HASH, algorithms=["HS256"])
session_key = session_payload["sid"]
except (KeyError, PyJWTError):
pass
@ -121,7 +114,7 @@ class SessionMiddleware(UpstreamSessionMiddleware):
}
if request.user.is_authenticated:
payload["sub"] = request.user.uid
value = encode(payload=payload, key=get_signing_hash())
value = encode(payload=payload, key=SIGNING_HASH)
if settings.TEST:
value = request.session.session_key
response.set_cookie(

View File

@ -4,7 +4,6 @@ import importlib
import logging
import os
from hashlib import sha512
from pathlib import Path
from urllib.parse import quote_plus
import structlog
@ -20,9 +19,11 @@ from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BAC
LOGGER = structlog.get_logger()
BASE_DIR = Path(__file__).absolute().parent.parent.parent
STATICFILES_DIRS = [BASE_DIR / Path("web")]
MEDIA_ROOT = BASE_DIR / Path("media")
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
STATIC_ROOT = BASE_DIR + "/static"
STATICFILES_DIRS = [BASE_DIR + "/web"]
MEDIA_ROOT = BASE_DIR + "/media"
DEBUG = CONFIG.y_bool("debug")
SECRET_KEY = CONFIG.y("secret_key")

View File

@ -55,7 +55,7 @@ class LDAPBackend(InbuiltBackend):
"""Attempt authentication by binding to the LDAP server as `user`. This
method should be avoided as its slow to do the bind."""
# Try to bind as new user
LOGGER.debug("Attempting to bind as user", user=user)
LOGGER.debug("Attempting Binding as user", user=user)
try:
temp_connection = source.connection(
connection_kwargs={
@ -65,8 +65,8 @@ class LDAPBackend(InbuiltBackend):
)
temp_connection.bind()
return user
except LDAPInvalidCredentialsResult as exc:
LOGGER.debug("invalid LDAP credentials", user=user, exc=exc)
except LDAPException as exc:
LOGGER.warning("failed to bind to LDAP", exc=exc)
except LDAPInvalidCredentialsResult as exception:
LOGGER.debug("LDAPInvalidCredentialsResult", user=user, error=exception)
except LDAPException as exception:
LOGGER.warning(exception)
return None

View File

@ -6,7 +6,6 @@ from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from ldap3.core.exceptions import LDAPOperationResult
from rest_framework.serializers import ValidationError
from structlog.stdlib import get_logger
from authentik.core.models import User
from authentik.core.signals import password_changed
@ -21,8 +20,6 @@ from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
from authentik.sources.ldap.tasks import ldap_sync
from authentik.stages.prompt.signals import password_validate
LOGGER = get_logger()
@receiver(post_save, sender=LDAPSource)
def sync_ldap_source_on_save(sender, instance: LDAPSource, **_):
@ -70,13 +67,9 @@ def ldap_sync_password(sender, user: User, password: str, **_):
try:
changer.change_password(user, password)
except LDAPOperationResult as exc:
LOGGER.warning("failed to set LDAP password", exc=exc)
Event.new(
EventAction.CONFIGURATION_ERROR,
message=(
"Failed to change password in LDAP source due to remote error: "
f"{exc.result}, {exc.message}, {exc.description}"
),
message=f"Result: {exc.result}, Description {exc.description}",
source=source,
).set_user(user).save()
raise ValidationError("Failed to set password") from exc

View File

@ -135,9 +135,9 @@ class BaseLDAPSynchronizer:
if key == "attributes":
continue
setattr(instance, key, value)
final_attributes = {}
MERGE_LIST_UNIQUE.merge(final_attributes, instance.attributes)
MERGE_LIST_UNIQUE.merge(final_attributes, data.get("attributes", {}))
instance.attributes = final_attributes
final_atttributes = {}
MERGE_LIST_UNIQUE.merge(final_atttributes, instance.attributes)
MERGE_LIST_UNIQUE.merge(final_atttributes, data.get("attributes", {}))
instance.attributes = final_atttributes
instance.save()
return (instance, False)

View File

@ -26,7 +26,6 @@ class SAMLSourceSerializer(SourceSerializer):
"allow_idp_initiated",
"name_id_policy",
"binding_type",
"verification_kp",
"signing_kp",
"digest_algorithm",
"signature_algorithm",
@ -56,7 +55,6 @@ class SAMLSourceViewSet(UsedByMixin, ModelViewSet):
"allow_idp_initiated",
"name_id_policy",
"binding_type",
"verification_kp",
"signing_kp",
"digest_algorithm",
"signature_algorithm",

View File

@ -1,53 +0,0 @@
# Generated by Django 4.1.7 on 2023-05-19 21:55
import django.db.models.deletion
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def migrate_verification_cert(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
"""Migrate signing cert to verification_kp for backwards compat"""
SAMLSource = apps.get_model("authentik_sources_saml", "samlsource")
for source in SAMLSource.objects.using(schema_editor.connection.alias).all():
source.verification_kp = source.signing_kp
source.save()
class Migration(migrations.Migration):
dependencies = [
("authentik_crypto", "0004_alter_certificatekeypair_name"),
("authentik_sources_saml", "0012_usersamlsourceconnection"),
]
operations = [
migrations.AddField(
model_name="samlsource",
name="verification_kp",
field=models.ForeignKey(
blank=True,
default=None,
help_text="When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="authentik_crypto.certificatekeypair",
verbose_name="Verification Certificate",
),
),
migrations.RunPython(migrate_verification_cert),
migrations.AlterField(
model_name="samlsource",
name="signing_kp",
field=models.ForeignKey(
blank=True,
default=None,
help_text="Keypair used to sign outgoing Responses going to the Identity Provider.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="authentik_crypto.certificatekeypair",
verbose_name="Signing Keypair",
),
),
]

View File

@ -121,27 +121,16 @@ class SAMLSource(Source):
),
)
verification_kp = models.ForeignKey(
CertificateKeyPair,
default=None,
null=True,
blank=True,
help_text=_(
"When selected, incoming assertion's Signatures will be validated against this "
"certificate. To allow unsigned Requests, leave on default."
),
on_delete=models.SET_NULL,
verbose_name=_("Verification Certificate"),
related_name="+",
)
signing_kp = models.ForeignKey(
CertificateKeyPair,
default=None,
null=True,
blank=True,
help_text=_("Keypair used to sign outgoing Responses going to the Identity Provider."),
on_delete=models.SET_NULL,
null=True,
verbose_name=_("Signing Keypair"),
help_text=_(
"Keypair which is used to sign outgoing requests. Leave empty to disable signing."
),
on_delete=models.SET_DEFAULT,
)
digest_algorithm = models.CharField(

View File

@ -21,7 +21,7 @@ from authentik.core.models import (
from authentik.core.sources.flow_manager import SourceFlowManager
from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.lib.utils.time import timedelta_from_string
from authentik.policies.utils import delete_none_values
from authentik.policies.utils import delete_none_keys
from authentik.sources.saml.exceptions import (
InvalidSignature,
MismatchedRequestID,
@ -72,7 +72,7 @@ class ResponseProcessor:
self._root_xml = b64decode(raw_response.encode())
self._root = fromstring(self._root_xml)
if self._source.verification_kp:
if self._source.signing_kp:
self._verify_signed()
self._verify_request_id()
self._verify_status()
@ -89,7 +89,7 @@ class ResponseProcessor:
ctx = xmlsec.SignatureContext()
key = xmlsec.Key.from_memory(
self._source.verification_kp.certificate_data,
self._source.signing_kp.certificate_data,
xmlsec.constants.KeyDataFormatCertPem,
)
ctx.key = key
@ -160,7 +160,7 @@ class ResponseProcessor:
self._source,
self._http_request,
name_id,
delete_none_values(self.get_attributes()),
delete_none_keys(self.get_attributes()),
)
def _get_name_id(self) -> "Element":
@ -237,7 +237,7 @@ class ResponseProcessor:
self._source,
self._http_request,
name_id.text,
delete_none_values(self.get_attributes()),
delete_none_keys(self.get_attributes()),
)

View File

@ -99,7 +99,7 @@ class AuthenticatorSMSStage(ConfigurableStage, FriendlyNamedStage, Stage):
"From": self.from_number,
"To": device.phone_number,
"Body": token,
"Message": str(self.get_message(token)),
"Message": self.get_message(token),
}
if self.mapping:

View File

@ -20,7 +20,6 @@ from authentik.flows.models import FlowDesignation, NotConfiguredAction, Stage
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
from authentik.lib.utils.time import timedelta_from_string
from authentik.root.install_id import get_install_id
from authentik.stages.authenticator_sms.models import SMSDevice
from authentik.stages.authenticator_validate.challenge import (
DeviceChallenge,
@ -317,7 +316,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
def cookie_jwt_key(self) -> str:
"""Signing key for MFA Cookie for this stage"""
return sha256(
f"{get_install_id()}:{self.executor.current_stage.pk.hex}".encode("ascii")
f"{settings.SECRET_KEY}:{self.executor.current_stage.pk.hex}".encode("ascii")
).hexdigest()
def check_mfa_cookie(self, allowed_devices: list[Device]):

View File

@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from hashlib import sha256
from time import sleep
from django.conf import settings
from django.test.client import RequestFactory
from django.urls.base import reverse
from django_otp.oath import TOTP
@ -16,7 +17,6 @@ from authentik.flows.stage import StageView
from authentik.flows.tests import FlowTestCase
from authentik.flows.views.executor import FlowExecutorView
from authentik.lib.generators import generate_id
from authentik.root.install_id import get_install_id
from authentik.stages.authenticator_validate.challenge import (
get_challenge_for_device,
validate_challenge_code,
@ -194,7 +194,7 @@ class AuthenticatorValidateStageTOTPTests(FlowTestCase):
"stage": stage.pk.hex + generate_id(),
"exp": (datetime.now() + timedelta(days=3)).timestamp(),
},
key=sha256(f"{get_install_id()}:{stage.pk.hex}".encode("ascii")).hexdigest(),
key=sha256(f"{settings.SECRET_KEY}:{stage.pk.hex}".encode("ascii")).hexdigest(),
)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
@ -233,7 +233,7 @@ class AuthenticatorValidateStageTOTPTests(FlowTestCase):
"stage": stage.pk.hex,
"exp": (datetime.now() + timedelta(days=3)).timestamp(),
},
key=sha256(f"{get_install_id()}:{stage.pk.hex}".encode("ascii")).hexdigest(),
key=sha256(f"{settings.SECRET_KEY}:{stage.pk.hex}".encode("ascii")).hexdigest(),
)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
@ -272,7 +272,7 @@ class AuthenticatorValidateStageTOTPTests(FlowTestCase):
"stage": stage.pk.hex,
"exp": (datetime.now() - timedelta(days=3)).timestamp(),
},
key=sha256(f"{get_install_id()}:{stage.pk.hex}".encode("ascii")).hexdigest(),
key=sha256(f"{settings.SECRET_KEY}:{stage.pk.hex}".encode("ascii")).hexdigest(),
)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),

View File

@ -8,7 +8,7 @@ from authentik.flows.models import Stage
class DenyStage(Stage):
"""Cancels the current flow."""
"""Cancells the current flow."""
@property
def serializer(self) -> type[BaseSerializer]:

View File

@ -5,10 +5,10 @@ from authentik.flows.stage import StageView
class DenyStageView(StageView):
"""Cancels the current flow"""
"""Cancells the current flow"""
def get(self, request: HttpRequest) -> HttpResponse:
"""Cancels the current flow"""
"""Cancells the current flow"""
return self.executor.stage_invalid()
def post(self, request: HttpRequest) -> HttpResponse:

View File

@ -6,7 +6,6 @@ from django.db import transaction
from django.db.utils import IntegrityError, InternalError
from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _
from rest_framework.exceptions import ValidationError
from authentik.core.middleware import SESSION_KEY_IMPERSONATE_USER
from authentik.core.models import USER_ATTRIBUTE_SOURCES, User, UserSourceConnection
@ -149,11 +148,7 @@ class UserWriteStageView(StageView):
and SESSION_KEY_IMPERSONATE_USER not in self.request.session
):
should_update_session = True
try:
self.update_user(user)
except ValidationError as exc:
self.logger.warning("failed to update user", exc=exc)
return self.executor.stage_invalid(_("Failed to update user. Please try again later."))
self.update_user(user)
# Extra check to prevent flows from saving a user with a blank username
if user.username == "":
self.logger.warning("Aborting write to empty username", user=user)
@ -167,7 +162,7 @@ class UserWriteStageView(StageView):
user.ak_groups.add(*self.executor.plan.context[PLAN_CONTEXT_GROUPS])
except (IntegrityError, ValueError, TypeError, InternalError) as exc:
self.logger.warning("Failed to save user", exc=exc)
return self.executor.stage_invalid(_("Failed to update user. Please try again later."))
return self.executor.stage_invalid(_("Failed to save user"))
user_write.send(sender=self, request=request, user=user, data=data, created=user_created)
# Check if the password has been updated, and update the session auth hash
if should_update_session:

View File

@ -2560,42 +2560,6 @@
"$ref": "#/$defs/model_authentik_core.token"
}
}
},
{
"type": "object",
"required": [
"model",
"identifiers"
],
"properties": {
"model": {
"const": "authentik_blueprints.metaapplyblueprint"
},
"id": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"absent",
"present",
"created"
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"attrs": {
"$ref": "#/$defs/model_authentik_blueprints.metaapplyblueprint"
},
"identifiers": {
"$ref": "#/$defs/model_authentik_blueprints.metaapplyblueprint"
}
}
}
]
}
@ -3888,7 +3852,8 @@
},
"required": [
"username",
"name"
"name",
"groups"
],
"title": "User"
},
@ -4079,7 +4044,8 @@
},
"required": [
"username",
"name"
"name",
"groups"
],
"title": "User"
},
@ -4274,7 +4240,8 @@
},
"required": [
"username",
"name"
"name",
"groups"
],
"title": "User"
},
@ -5254,15 +5221,10 @@
],
"title": "Binding type"
},
"verification_kp": {
"type": "integer",
"title": "Verification Certificate",
"description": "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
},
"signing_kp": {
"type": "integer",
"title": "Signing Keypair",
"description": "Keypair used to sign outgoing Responses going to the Identity Provider."
"description": "Keypair which is used to sign outgoing requests. Leave empty to disable signing."
},
"digest_algorithm": {
"type": "string",
@ -6421,7 +6383,8 @@
},
"required": [
"username",
"name"
"name",
"groups"
],
"title": "User"
},
@ -7156,7 +7119,8 @@
},
"required": [
"username",
"name"
"name",
"groups"
],
"title": "User"
},
@ -8228,11 +8192,6 @@
"type": "string",
"minLength": 1,
"title": "Path"
},
"password": {
"type": "string",
"minLength": 1,
"title": "Password"
}
},
"required": []
@ -8355,21 +8314,6 @@
}
},
"required": []
},
"model_authentik_blueprints.metaapplyblueprint": {
"type": "object",
"properties": {
"identifiers": {
"type": "object",
"additionalProperties": true,
"title": "Identifiers"
},
"required": {
"type": "boolean",
"title": "Required"
}
},
"required": []
}
}
}

View File

@ -21,7 +21,7 @@ entries:
# photos supports URLs to images, however authentik might return data URIs
avatar = request.user.avatar
photos = None
photos = []
if "://" in avatar:
photos = [{"value": avatar, "type": "photo"}]
@ -31,11 +31,11 @@ entries:
emails = []
if request.user.email != "":
emails = [{
emails.append({
"value": request.user.email,
"type": "other",
"primary": True,
}]
})
return {
"userName": request.user.username,
"name": {

View File

@ -32,7 +32,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.4.1}
restart: unless-stopped
command: server
environment:
@ -49,11 +49,8 @@ services:
ports:
- "${COMPOSE_PORT_HTTP:-9000}:9000"
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
depends_on:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.4.1}
restart: unless-stopped
command: worker
environment:
@ -76,9 +73,6 @@ services:
- ./custom-templates:/templates
env_file:
- .env
depends_on:
- postgresql
- redis
volumes:
database:

6
go.mod
View File

@ -23,10 +23,10 @@ require (
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba
github.com/pires/go-proxyproto v0.7.0
github.com/prometheus/client_golang v1.15.1
github.com/sirupsen/logrus v1.9.2
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.3
goauthentik.io/api/v3 v3.2023052.1
github.com/stretchr/testify v1.8.2
goauthentik.io/api/v3 v3.2023041.12
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.8.0
golang.org/x/sync v0.2.0

13
go.sum
View File

@ -200,8 +200,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
@ -211,6 +211,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@ -218,8 +219,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
@ -240,8 +241,8 @@ go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvx
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
goauthentik.io/api/v3 v3.2023052.1 h1:Sp3sBfkdBJCVTAxZte5fvBU4s0IZm6bqqli8ZawiER4=
goauthentik.io/api/v3 v3.2023052.1/go.mod h1:nYECml4jGbp/541hj8GcylKQG1gVBsKppHy4+7G8u4U=
goauthentik.io/api/v3 v3.2023041.12 h1:lk8eCWYW/P8U4r10RgtIq2NyaAqZ3KKrKc7eierV6aY=
goauthentik.io/api/v3 v3.2023041.12/go.mod h1:nYECml4jGbp/541hj8GcylKQG1gVBsKppHy4+7G8u4U=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=

View File

@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion())
}
const VERSION = "2023.5.2"
const VERSION = "2023.4.1"

View File

@ -15,7 +15,6 @@ from authentik import get_full_version
from authentik.lib.config import CONFIG
from authentik.lib.utils.http import get_http_session
from authentik.lib.utils.reflection import get_env
from authentik.root.install_id import get_install_id_raw
from lifecycle.worker import DjangoUvicornWorker
if TYPE_CHECKING:
@ -149,7 +148,9 @@ if not CONFIG.y_bool("disable_startup_analytics", False):
),
},
headers={
"User-Agent": sha512(get_install_id_raw().encode("ascii")).hexdigest()[:16],
"User-Agent": sha512(str(CONFIG.y("secret_key")).encode("ascii")).hexdigest()[
:16
],
"Content-Type": "application/json",
},
timeout=5,

View File

@ -1,45 +0,0 @@
# flake8: noqa
from uuid import uuid4
from authentik.lib.config import CONFIG
from lifecycle.migrate import BaseMigration
SQL_STATEMENT = """BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS authentik_install_id (
id TEXT NOT NULL
);
COMMIT;"""
class Migration(BaseMigration):
def needs_migration(self) -> bool:
self.cur.execute(
"select * from information_schema.tables where table_name = 'authentik_install_id';"
)
return not bool(self.cur.rowcount)
def upgrade(self, migrate=False):
self.cur.execute(SQL_STATEMENT)
self.con.commit()
if migrate:
# If we already have migrations in the database, assume we're upgrading an existing install
# and set the install id to the secret key
self.cur.execute(
"INSERT INTO authentik_install_id (id) VALUES (%s)", (CONFIG.y("secret_key"),)
)
else:
# Otherwise assume a new install, generate an install ID based on a UUID
install_id = str(uuid4())
self.cur.execute("INSERT INTO authentik_install_id (id) VALUES (%s)", (install_id,))
self.con.commit()
def run(self):
self.cur.execute(
"select * from information_schema.tables where table_name = 'django_migrations';"
)
if not bool(self.cur.rowcount):
# No django_migrations table, so generate a new id
return self.upgrade(migrate=False)
self.cur.execute("select count(*) from django_migrations;")
migrations = self.cur.fetchone()[0]
return self.upgrade(migrate=migrations > 0)

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-05-21 21:59+0000\n"
"POT-Creation-Date: 2023-05-10 17:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -31,16 +31,12 @@ msgstr ""
msgid "Validation Error"
msgstr ""
#: authentik/blueprints/api.py:43
msgid "Blueprint file does not exist"
msgstr ""
#: authentik/blueprints/api.py:54
#: authentik/blueprints/api.py:53
#, python-format
msgid "Failed to validate blueprint: %(logs)s"
msgstr ""
#: authentik/blueprints/api.py:59
#: authentik/blueprints/api.py:58
msgid "Either path or content must be set."
msgstr ""
@ -325,105 +321,105 @@ msgstr ""
msgid "Certificate-Key Pairs"
msgstr ""
#: authentik/events/models.py:290
#: authentik/events/models.py:293
msgid "Event"
msgstr ""
#: authentik/events/models.py:291
#: authentik/events/models.py:294
msgid "Events"
msgstr ""
#: authentik/events/models.py:297
#: authentik/events/models.py:300
msgid "authentik inbuilt notifications"
msgstr ""
#: authentik/events/models.py:298
#: authentik/events/models.py:301
msgid "Generic Webhook"
msgstr ""
#: authentik/events/models.py:299
#: authentik/events/models.py:302
msgid "Slack Webhook (Slack/Discord)"
msgstr ""
#: authentik/events/models.py:300
#: authentik/events/models.py:303
msgid "Email"
msgstr ""
#: authentik/events/models.py:318
#: authentik/events/models.py:321
msgid ""
"Only send notification once, for example when sending a webhook into a chat "
"channel."
msgstr ""
#: authentik/events/models.py:383
#: authentik/events/models.py:386
msgid "Severity"
msgstr ""
#: authentik/events/models.py:388
#: authentik/events/models.py:391
msgid "Dispatched for user"
msgstr ""
#: authentik/events/models.py:397
#: authentik/events/models.py:400
msgid "Event user"
msgstr ""
#: authentik/events/models.py:484
#: authentik/events/models.py:487
msgid "Notification Transport"
msgstr ""
#: authentik/events/models.py:485
#: authentik/events/models.py:488
msgid "Notification Transports"
msgstr ""
#: authentik/events/models.py:491
#: authentik/events/models.py:494
msgid "Notice"
msgstr ""
#: authentik/events/models.py:492
#: authentik/events/models.py:495
msgid "Warning"
msgstr ""
#: authentik/events/models.py:493
#: authentik/events/models.py:496
msgid "Alert"
msgstr ""
#: authentik/events/models.py:518
#: authentik/events/models.py:521
msgid "Notification"
msgstr ""
#: authentik/events/models.py:519
#: authentik/events/models.py:522
msgid "Notifications"
msgstr ""
#: authentik/events/models.py:529
#: authentik/events/models.py:532
msgid ""
"Select which transports should be used to notify the user. If none are "
"selected, the notification will only be shown in the authentik UI."
msgstr ""
#: authentik/events/models.py:537
#: authentik/events/models.py:540
msgid "Controls which severity level the created notifications will have."
msgstr ""
#: authentik/events/models.py:542
#: authentik/events/models.py:545
msgid ""
"Define which group of users this notification should be sent and shown to. "
"If left empty, Notification won't ben sent."
msgstr ""
#: authentik/events/models.py:560
#: authentik/events/models.py:563
msgid "Notification Rule"
msgstr ""
#: authentik/events/models.py:561
#: authentik/events/models.py:564
msgid "Notification Rules"
msgstr ""
#: authentik/events/models.py:581
#: authentik/events/models.py:584
msgid "Webhook Mapping"
msgstr ""
#: authentik/events/models.py:582
#: authentik/events/models.py:585
msgid "Webhook Mappings"
msgstr ""
@ -1287,49 +1283,49 @@ msgid ""
"minutes=2;seconds=3)."
msgstr ""
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:150
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:139
msgid "SHA1"
msgstr ""
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:151
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:140
msgid "SHA256"
msgstr ""
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:152
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:141
msgid "SHA384"
msgstr ""
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:153
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:142
msgid "SHA512"
msgstr ""
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:160
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:149
msgid "RSA-SHA1"
msgstr ""
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:161
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:150
msgid "RSA-SHA256"
msgstr ""
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:162
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:151
msgid "RSA-SHA384"
msgstr ""
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:163
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:152
msgid "RSA-SHA512"
msgstr ""
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:164
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:153
msgid "DSA-SHA1"
msgstr ""
#: authentik/providers/saml/models.py:124 authentik/sources/saml/models.py:130
#: authentik/providers/saml/models.py:124
msgid ""
"When selected, incoming assertion's Signatures will be validated against "
"this certificate. To allow unsigned Requests, leave on default."
msgstr ""
#: authentik/providers/saml/models.py:128 authentik/sources/saml/models.py:134
#: authentik/providers/saml/models.py:128
msgid "Verification Certificate"
msgstr ""
@ -1337,7 +1333,7 @@ msgstr ""
msgid "Keypair used to sign outgoing Responses going to the Service Provider."
msgstr ""
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:144
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:129
msgid "Signing Keypair"
msgstr ""
@ -1385,33 +1381,33 @@ msgstr ""
msgid "SCIM Mappings"
msgstr ""
#: authentik/providers/scim/tasks.py:52
#: authentik/providers/scim/tasks.py:50
msgid "Starting full SCIM sync"
msgstr ""
#: authentik/providers/scim/tasks.py:59
#: authentik/providers/scim/tasks.py:57
#, python-format
msgid "Syncing page %(page)d of users"
msgstr ""
#: authentik/providers/scim/tasks.py:63
#: authentik/providers/scim/tasks.py:61
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr ""
#: authentik/providers/scim/tasks.py:92
#: authentik/providers/scim/tasks.py:90
#, python-format
msgid "Failed to sync user %(user_name)s due to remote error: %(error)s"
msgid "Failed to sync user due to remote error %(name)s: %(error)s"
msgstr ""
#: authentik/providers/scim/tasks.py:103 authentik/providers/scim/tasks.py:144
#: authentik/providers/scim/tasks.py:101 authentik/providers/scim/tasks.py:142
#, python-format
msgid "Stopping sync due to error: %(error)s"
msgstr ""
#: authentik/providers/scim/tasks.py:133
#: authentik/providers/scim/tasks.py:131
#, python-format
msgid "Failed to sync group %(group_name)s due to remote error: %(error)s"
msgid "Failed to sync group due to remote error %(name)s: %(error)s"
msgstr ""
#: authentik/recovery/management/commands/create_admin_group.py:11
@ -1502,7 +1498,7 @@ msgstr ""
msgid "LDAP Property Mappings"
msgstr ""
#: authentik/sources/ldap/signals.py:59
#: authentik/sources/ldap/signals.py:56
msgid "Password does not match Active Directory Complexity."
msgstr ""
@ -1768,23 +1764,25 @@ msgid ""
"manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr ""
#: authentik/sources/saml/models.py:142
msgid "Keypair used to sign outgoing Responses going to the Identity Provider."
#: authentik/sources/saml/models.py:131
msgid ""
"Keypair which is used to sign outgoing requests. Leave empty to disable "
"signing."
msgstr ""
#: authentik/sources/saml/models.py:226
#: authentik/sources/saml/models.py:215
msgid "SAML Source"
msgstr ""
#: authentik/sources/saml/models.py:227
#: authentik/sources/saml/models.py:216
msgid "SAML Sources"
msgstr ""
#: authentik/sources/saml/models.py:242
#: authentik/sources/saml/models.py:231
msgid "User SAML Source Connection"
msgstr ""
#: authentik/sources/saml/models.py:243
#: authentik/sources/saml/models.py:232
msgid "User SAML Source Connections"
msgstr ""
@ -2108,10 +2106,6 @@ msgid ""
" "
msgstr ""
#: authentik/stages/identification/api.py:20
msgid "When no user fields are selected, at least one source must be selected"
msgstr ""
#: authentik/stages/identification/models.py:29
msgid ""
"Fields of the user object to match against. (Hold shift to select multiple "
@ -2403,17 +2397,16 @@ msgstr ""
msgid "User Write Stages"
msgstr ""
#: authentik/stages/user_write/stage.py:133
#: authentik/stages/user_write/stage.py:132
msgid "No Pending data."
msgstr ""
#: authentik/stages/user_write/stage.py:139
#: authentik/stages/user_write/stage.py:138
msgid "No user found and can't create new user."
msgstr ""
#: authentik/stages/user_write/stage.py:156
#: authentik/stages/user_write/stage.py:170
msgid "Failed to update user. Please try again later."
#: authentik/stages/user_write/stage.py:165
msgid "Failed to save user"
msgstr ""
#: authentik/tenants/models.py:23

View File

@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-05-21 21:59+0000\n"
"POT-Creation-Date: 2023-05-10 17:31+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2023\n"
"Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n"
@ -37,16 +37,12 @@ msgstr "通用 API 错误"
msgid "Validation Error"
msgstr "校验错误"
#: authentik/blueprints/api.py:43
msgid "Blueprint file does not exist"
msgstr "蓝图文件不存在"
#: authentik/blueprints/api.py:54
#: authentik/blueprints/api.py:53
#, python-format
msgid "Failed to validate blueprint: %(logs)s"
msgstr "验证蓝图失败:%(logs)s"
#: authentik/blueprints/api.py:59
#: authentik/blueprints/api.py:58
msgid "Either path or content must be set."
msgstr "必须设置路径或内容。"
@ -341,105 +337,105 @@ msgstr "证书密钥对"
msgid "Certificate-Key Pairs"
msgstr "证书密钥对"
#: authentik/events/models.py:290
#: authentik/events/models.py:293
msgid "Event"
msgstr "事件"
#: authentik/events/models.py:291
#: authentik/events/models.py:294
msgid "Events"
msgstr "事件"
#: authentik/events/models.py:297
#: authentik/events/models.py:300
msgid "authentik inbuilt notifications"
msgstr "authentik 内置通知"
#: authentik/events/models.py:298
#: authentik/events/models.py:301
msgid "Generic Webhook"
msgstr "通用 Webhook"
#: authentik/events/models.py:299
#: authentik/events/models.py:302
msgid "Slack Webhook (Slack/Discord)"
msgstr "Slack WebhookSlack/Discord"
#: authentik/events/models.py:300
#: authentik/events/models.py:303
msgid "Email"
msgstr "电子邮箱"
#: authentik/events/models.py:318
#: authentik/events/models.py:321
msgid ""
"Only send notification once, for example when sending a webhook into a chat "
"channel."
msgstr "仅发送一次通知,例如在向聊天频道发送 Webhook 时。"
#: authentik/events/models.py:383
#: authentik/events/models.py:386
msgid "Severity"
msgstr "严重程度"
#: authentik/events/models.py:388
#: authentik/events/models.py:391
msgid "Dispatched for user"
msgstr "为用户分派"
#: authentik/events/models.py:397
#: authentik/events/models.py:400
msgid "Event user"
msgstr "事件用户"
#: authentik/events/models.py:484
#: authentik/events/models.py:487
msgid "Notification Transport"
msgstr "通知传输"
#: authentik/events/models.py:485
#: authentik/events/models.py:488
msgid "Notification Transports"
msgstr "通知传输"
#: authentik/events/models.py:491
#: authentik/events/models.py:494
msgid "Notice"
msgstr "通知"
#: authentik/events/models.py:492
#: authentik/events/models.py:495
msgid "Warning"
msgstr "警告"
#: authentik/events/models.py:493
#: authentik/events/models.py:496
msgid "Alert"
msgstr "注意"
#: authentik/events/models.py:518
#: authentik/events/models.py:521
msgid "Notification"
msgstr "通知"
#: authentik/events/models.py:519
#: authentik/events/models.py:522
msgid "Notifications"
msgstr "通知"
#: authentik/events/models.py:529
#: authentik/events/models.py:532
msgid ""
"Select which transports should be used to notify the user. If none are "
"selected, the notification will only be shown in the authentik UI."
msgstr "选择应使用哪些传输方式来通知用户。如果未选择任何内容,则通知将仅显示在 authentik UI 中。"
#: authentik/events/models.py:537
#: authentik/events/models.py:540
msgid "Controls which severity level the created notifications will have."
msgstr "控制被创建的通知的严重性级别。"
#: authentik/events/models.py:542
#: authentik/events/models.py:545
msgid ""
"Define which group of users this notification should be sent and shown to. "
"If left empty, Notification won't ben sent."
msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。"
#: authentik/events/models.py:560
#: authentik/events/models.py:563
msgid "Notification Rule"
msgstr "通知规则"
#: authentik/events/models.py:561
#: authentik/events/models.py:564
msgid "Notification Rules"
msgstr "通知规则"
#: authentik/events/models.py:581
#: authentik/events/models.py:584
msgid "Webhook Mapping"
msgstr "Webhook 映射"
#: authentik/events/models.py:582
#: authentik/events/models.py:585
msgid "Webhook Mappings"
msgstr "Webhook 映射"
@ -1316,49 +1312,49 @@ msgid ""
"hours=1;minutes=2;seconds=3)."
msgstr "从当前时间经过多久时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:150
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:139
msgid "SHA1"
msgstr "SHA1"
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:151
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:140
msgid "SHA256"
msgstr "SHA256"
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:152
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:141
msgid "SHA384"
msgstr "SHA384"
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:153
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:142
msgid "SHA512"
msgstr "SHA512"
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:160
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:149
msgid "RSA-SHA1"
msgstr "RSA-SHA1"
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:161
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:150
msgid "RSA-SHA256"
msgstr "RSA-SHA256"
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:162
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:151
msgid "RSA-SHA384"
msgstr "RSA-SHA384"
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:163
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:152
msgid "RSA-SHA512"
msgstr "RSA-SHA512"
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:164
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:153
msgid "DSA-SHA1"
msgstr "DSA-SHA1"
#: authentik/providers/saml/models.py:124 authentik/sources/saml/models.py:130
#: authentik/providers/saml/models.py:124
msgid ""
"When selected, incoming assertion's Signatures will be validated against "
"this certificate. To allow unsigned Requests, leave on default."
msgstr "选中后,传入断言的签名将根据此证书进行验证。要允许未签名的请求,请保留默认值。"
#: authentik/providers/saml/models.py:128 authentik/sources/saml/models.py:134
#: authentik/providers/saml/models.py:128
msgid "Verification Certificate"
msgstr "验证证书"
@ -1366,7 +1362,7 @@ msgstr "验证证书"
msgid "Keypair used to sign outgoing Responses going to the Service Provider."
msgstr "密钥对,用于签署发送给服务提供程序的传出响应。"
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:144
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:129
msgid "Signing Keypair"
msgstr "签名密钥对"
@ -1414,34 +1410,34 @@ msgstr "SCIM 映射"
msgid "SCIM Mappings"
msgstr "SCIM 映射"
#: authentik/providers/scim/tasks.py:52
#: authentik/providers/scim/tasks.py:50
msgid "Starting full SCIM sync"
msgstr "开始全量 SCIM 同步"
#: authentik/providers/scim/tasks.py:59
#: authentik/providers/scim/tasks.py:57
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "正在同步用户页面 %(page)d"
#: authentik/providers/scim/tasks.py:63
#: authentik/providers/scim/tasks.py:61
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "正在同步群组页面 %(page)d"
#: authentik/providers/scim/tasks.py:92
#: authentik/providers/scim/tasks.py:90
#, python-format
msgid "Failed to sync user %(user_name)s due to remote error: %(error)s"
msgstr "由于远端错误,同步用户 %(user_name)s 失败:%(error)s"
msgid "Failed to sync user due to remote error %(name)s: %(error)s"
msgstr "由于远端错误 %(name)s,同步用户失败:%(error)s"
#: authentik/providers/scim/tasks.py:103 authentik/providers/scim/tasks.py:144
#: authentik/providers/scim/tasks.py:101 authentik/providers/scim/tasks.py:142
#, python-format
msgid "Stopping sync due to error: %(error)s"
msgstr "由于以下错误,同步停止:%(error)s"
#: authentik/providers/scim/tasks.py:133
#: authentik/providers/scim/tasks.py:131
#, python-format
msgid "Failed to sync group %(group_name)s due to remote error: %(error)s"
msgstr "由于远端错误,同步组 %(group_name)s 失败:%(error)s"
msgid "Failed to sync group due to remote error %(name)s: %(error)s"
msgstr "由于远端错误 %(name)s,同步群组失败:%(error)s"
#: authentik/recovery/management/commands/create_admin_group.py:11
msgid "Create admin group if the default group gets deleted."
@ -1531,7 +1527,7 @@ msgstr "LDAP 属性映射"
msgid "LDAP Property Mappings"
msgstr "LDAP 属性映射"
#: authentik/sources/ldap/signals.py:59
#: authentik/sources/ldap/signals.py:56
msgid "Password does not match Active Directory Complexity."
msgstr "密码与 Active Directory 复杂度不匹配。"
@ -1801,24 +1797,25 @@ msgstr ""
"删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式 'transient' "
"且用户未手动登出的情况。格式hours=1;minutes=2;seconds=3。"
#: authentik/sources/saml/models.py:142
#: authentik/sources/saml/models.py:131
msgid ""
"Keypair used to sign outgoing Responses going to the Identity Provider."
msgstr "密钥对,用于签署发送给身份提供程序的传出响应。"
"Keypair which is used to sign outgoing requests. Leave empty to disable "
"signing."
msgstr "用于签署传出请求的密钥对。留空则禁用签名。"
#: authentik/sources/saml/models.py:226
#: authentik/sources/saml/models.py:215
msgid "SAML Source"
msgstr "SAML 源"
#: authentik/sources/saml/models.py:227
#: authentik/sources/saml/models.py:216
msgid "SAML Sources"
msgstr "SAML 源"
#: authentik/sources/saml/models.py:242
#: authentik/sources/saml/models.py:231
msgid "User SAML Source Connection"
msgstr "用户 SAML 源连接"
#: authentik/sources/saml/models.py:243
#: authentik/sources/saml/models.py:232
msgid "User SAML Source Connections"
msgstr "用户 SAML 源连接"
@ -2153,10 +2150,6 @@ msgstr ""
" 这是一封测试电子邮件,用于通知您已成功配置 authentik 电子邮件。\n"
" "
#: authentik/stages/identification/api.py:20
msgid "When no user fields are selected, at least one source must be selected"
msgstr "如果未选择用户字段,则至少要选择一个源"
#: authentik/stages/identification/models.py:29
msgid ""
"Fields of the user object to match against. (Hold shift to select multiple "
@ -2450,18 +2443,17 @@ msgstr "用户写入阶段"
msgid "User Write Stages"
msgstr "用户写入阶段"
#: authentik/stages/user_write/stage.py:133
#: authentik/stages/user_write/stage.py:132
msgid "No Pending data."
msgstr "没有待处理的数据。"
#: authentik/stages/user_write/stage.py:139
#: authentik/stages/user_write/stage.py:138
msgid "No user found and can't create new user."
msgstr "未找到用户并且无法创建新用户。"
#: authentik/stages/user_write/stage.py:156
#: authentik/stages/user_write/stage.py:170
msgid "Failed to update user. Please try again later."
msgstr "更新用户失败。请稍后重试。"
#: authentik/stages/user_write/stage.py:165
msgid "Failed to save user"
msgstr "保存用户失败"
#: authentik/tenants/models.py:23
msgid ""

View File

@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-05-21 21:59+0000\n"
"POT-Creation-Date: 2023-05-10 17:31+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2023\n"
"Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n"
@ -37,16 +37,12 @@ msgstr "通用 API 错误"
msgid "Validation Error"
msgstr "校验错误"
#: authentik/blueprints/api.py:43
msgid "Blueprint file does not exist"
msgstr "蓝图文件不存在"
#: authentik/blueprints/api.py:54
#: authentik/blueprints/api.py:53
#, python-format
msgid "Failed to validate blueprint: %(logs)s"
msgstr "验证蓝图失败:%(logs)s"
#: authentik/blueprints/api.py:59
#: authentik/blueprints/api.py:58
msgid "Either path or content must be set."
msgstr "必须设置路径或内容。"
@ -341,105 +337,105 @@ msgstr "证书密钥对"
msgid "Certificate-Key Pairs"
msgstr "证书密钥对"
#: authentik/events/models.py:290
#: authentik/events/models.py:293
msgid "Event"
msgstr "事件"
#: authentik/events/models.py:291
#: authentik/events/models.py:294
msgid "Events"
msgstr "事件"
#: authentik/events/models.py:297
#: authentik/events/models.py:300
msgid "authentik inbuilt notifications"
msgstr "authentik 内置通知"
#: authentik/events/models.py:298
#: authentik/events/models.py:301
msgid "Generic Webhook"
msgstr "通用 Webhook"
#: authentik/events/models.py:299
#: authentik/events/models.py:302
msgid "Slack Webhook (Slack/Discord)"
msgstr "Slack WebhookSlack/Discord"
#: authentik/events/models.py:300
#: authentik/events/models.py:303
msgid "Email"
msgstr "电子邮箱"
#: authentik/events/models.py:318
#: authentik/events/models.py:321
msgid ""
"Only send notification once, for example when sending a webhook into a chat "
"channel."
msgstr "仅发送一次通知,例如在向聊天频道发送 Webhook 时。"
#: authentik/events/models.py:383
#: authentik/events/models.py:386
msgid "Severity"
msgstr "严重程度"
#: authentik/events/models.py:388
#: authentik/events/models.py:391
msgid "Dispatched for user"
msgstr "为用户分派"
#: authentik/events/models.py:397
#: authentik/events/models.py:400
msgid "Event user"
msgstr "事件用户"
#: authentik/events/models.py:484
#: authentik/events/models.py:487
msgid "Notification Transport"
msgstr "通知传输"
#: authentik/events/models.py:485
#: authentik/events/models.py:488
msgid "Notification Transports"
msgstr "通知传输"
#: authentik/events/models.py:491
#: authentik/events/models.py:494
msgid "Notice"
msgstr "通知"
#: authentik/events/models.py:492
#: authentik/events/models.py:495
msgid "Warning"
msgstr "警告"
#: authentik/events/models.py:493
#: authentik/events/models.py:496
msgid "Alert"
msgstr "注意"
#: authentik/events/models.py:518
#: authentik/events/models.py:521
msgid "Notification"
msgstr "通知"
#: authentik/events/models.py:519
#: authentik/events/models.py:522
msgid "Notifications"
msgstr "通知"
#: authentik/events/models.py:529
#: authentik/events/models.py:532
msgid ""
"Select which transports should be used to notify the user. If none are "
"selected, the notification will only be shown in the authentik UI."
msgstr "选择应使用哪些传输方式来通知用户。如果未选择任何内容,则通知将仅显示在 authentik UI 中。"
#: authentik/events/models.py:537
#: authentik/events/models.py:540
msgid "Controls which severity level the created notifications will have."
msgstr "控制被创建的通知的严重性级别。"
#: authentik/events/models.py:542
#: authentik/events/models.py:545
msgid ""
"Define which group of users this notification should be sent and shown to. "
"If left empty, Notification won't ben sent."
msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。"
#: authentik/events/models.py:560
#: authentik/events/models.py:563
msgid "Notification Rule"
msgstr "通知规则"
#: authentik/events/models.py:561
#: authentik/events/models.py:564
msgid "Notification Rules"
msgstr "通知规则"
#: authentik/events/models.py:581
#: authentik/events/models.py:584
msgid "Webhook Mapping"
msgstr "Webhook 映射"
#: authentik/events/models.py:582
#: authentik/events/models.py:585
msgid "Webhook Mappings"
msgstr "Webhook 映射"
@ -1316,49 +1312,49 @@ msgid ""
"hours=1;minutes=2;seconds=3)."
msgstr "从当前时间经过多久时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:150
#: authentik/providers/saml/models.py:99 authentik/sources/saml/models.py:139
msgid "SHA1"
msgstr "SHA1"
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:151
#: authentik/providers/saml/models.py:100 authentik/sources/saml/models.py:140
msgid "SHA256"
msgstr "SHA256"
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:152
#: authentik/providers/saml/models.py:101 authentik/sources/saml/models.py:141
msgid "SHA384"
msgstr "SHA384"
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:153
#: authentik/providers/saml/models.py:102 authentik/sources/saml/models.py:142
msgid "SHA512"
msgstr "SHA512"
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:160
#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:149
msgid "RSA-SHA1"
msgstr "RSA-SHA1"
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:161
#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:150
msgid "RSA-SHA256"
msgstr "RSA-SHA256"
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:162
#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:151
msgid "RSA-SHA384"
msgstr "RSA-SHA384"
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:163
#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:152
msgid "RSA-SHA512"
msgstr "RSA-SHA512"
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:164
#: authentik/providers/saml/models.py:113 authentik/sources/saml/models.py:153
msgid "DSA-SHA1"
msgstr "DSA-SHA1"
#: authentik/providers/saml/models.py:124 authentik/sources/saml/models.py:130
#: authentik/providers/saml/models.py:124
msgid ""
"When selected, incoming assertion's Signatures will be validated against "
"this certificate. To allow unsigned Requests, leave on default."
msgstr "选中后,传入断言的签名将根据此证书进行验证。要允许未签名的请求,请保留默认值。"
#: authentik/providers/saml/models.py:128 authentik/sources/saml/models.py:134
#: authentik/providers/saml/models.py:128
msgid "Verification Certificate"
msgstr "验证证书"
@ -1366,7 +1362,7 @@ msgstr "验证证书"
msgid "Keypair used to sign outgoing Responses going to the Service Provider."
msgstr "密钥对,用于签署发送给服务提供程序的传出响应。"
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:144
#: authentik/providers/saml/models.py:138 authentik/sources/saml/models.py:129
msgid "Signing Keypair"
msgstr "签名密钥对"
@ -1414,34 +1410,34 @@ msgstr "SCIM 映射"
msgid "SCIM Mappings"
msgstr "SCIM 映射"
#: authentik/providers/scim/tasks.py:52
#: authentik/providers/scim/tasks.py:50
msgid "Starting full SCIM sync"
msgstr "开始全量 SCIM 同步"
#: authentik/providers/scim/tasks.py:59
#: authentik/providers/scim/tasks.py:57
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "正在同步用户页面 %(page)d"
#: authentik/providers/scim/tasks.py:63
#: authentik/providers/scim/tasks.py:61
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "正在同步群组页面 %(page)d"
#: authentik/providers/scim/tasks.py:92
#: authentik/providers/scim/tasks.py:90
#, python-format
msgid "Failed to sync user %(user_name)s due to remote error: %(error)s"
msgstr "由于远端错误,同步用户 %(user_name)s 失败:%(error)s"
msgid "Failed to sync user due to remote error %(name)s: %(error)s"
msgstr "由于远端错误 %(name)s,同步用户失败:%(error)s"
#: authentik/providers/scim/tasks.py:103 authentik/providers/scim/tasks.py:144
#: authentik/providers/scim/tasks.py:101 authentik/providers/scim/tasks.py:142
#, python-format
msgid "Stopping sync due to error: %(error)s"
msgstr "由于以下错误,同步停止:%(error)s"
#: authentik/providers/scim/tasks.py:133
#: authentik/providers/scim/tasks.py:131
#, python-format
msgid "Failed to sync group %(group_name)s due to remote error: %(error)s"
msgstr "由于远端错误,同步组 %(group_name)s 失败:%(error)s"
msgid "Failed to sync group due to remote error %(name)s: %(error)s"
msgstr "由于远端错误 %(name)s,同步群组失败:%(error)s"
#: authentik/recovery/management/commands/create_admin_group.py:11
msgid "Create admin group if the default group gets deleted."
@ -1531,7 +1527,7 @@ msgstr "LDAP 属性映射"
msgid "LDAP Property Mappings"
msgstr "LDAP 属性映射"
#: authentik/sources/ldap/signals.py:59
#: authentik/sources/ldap/signals.py:56
msgid "Password does not match Active Directory Complexity."
msgstr "密码与 Active Directory 复杂度不匹配。"
@ -1801,24 +1797,25 @@ msgstr ""
"删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式 'transient' "
"且用户未手动登出的情况。格式hours=1;minutes=2;seconds=3。"
#: authentik/sources/saml/models.py:142
#: authentik/sources/saml/models.py:131
msgid ""
"Keypair used to sign outgoing Responses going to the Identity Provider."
msgstr "密钥对,用于签署发送给身份提供程序的传出响应。"
"Keypair which is used to sign outgoing requests. Leave empty to disable "
"signing."
msgstr "用于签署传出请求的密钥对。留空则禁用签名。"
#: authentik/sources/saml/models.py:226
#: authentik/sources/saml/models.py:215
msgid "SAML Source"
msgstr "SAML 源"
#: authentik/sources/saml/models.py:227
#: authentik/sources/saml/models.py:216
msgid "SAML Sources"
msgstr "SAML 源"
#: authentik/sources/saml/models.py:242
#: authentik/sources/saml/models.py:231
msgid "User SAML Source Connection"
msgstr "用户 SAML 源连接"
#: authentik/sources/saml/models.py:243
#: authentik/sources/saml/models.py:232
msgid "User SAML Source Connections"
msgstr "用户 SAML 源连接"
@ -2153,10 +2150,6 @@ msgstr ""
" 这是一封测试电子邮件,用于通知您已成功配置 authentik 电子邮件。\n"
" "
#: authentik/stages/identification/api.py:20
msgid "When no user fields are selected, at least one source must be selected"
msgstr "如果未选择用户字段,则至少要选择一个源"
#: authentik/stages/identification/models.py:29
msgid ""
"Fields of the user object to match against. (Hold shift to select multiple "
@ -2450,18 +2443,17 @@ msgstr "用户写入阶段"
msgid "User Write Stages"
msgstr "用户写入阶段"
#: authentik/stages/user_write/stage.py:133
#: authentik/stages/user_write/stage.py:132
msgid "No Pending data."
msgstr "没有待处理的数据。"
#: authentik/stages/user_write/stage.py:139
#: authentik/stages/user_write/stage.py:138
msgid "No user found and can't create new user."
msgstr "未找到用户并且无法创建新用户。"
#: authentik/stages/user_write/stage.py:156
#: authentik/stages/user_write/stage.py:170
msgid "Failed to update user. Please try again later."
msgstr "更新用户失败。请稍后重试。"
#: authentik/stages/user_write/stage.py:165
msgid "Failed to save user"
msgstr "保存用户失败"
#: authentik/tenants/models.py:23
msgid ""

298
poetry.lock generated
View File

@ -878,72 +878,63 @@ files = [
[[package]]
name = "coverage"
version = "7.2.7"
version = "7.2.5"
description = "Code coverage measurement for Python"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"},
{file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"},
{file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"},
{file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"},
{file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"},
{file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"},
{file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"},
{file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"},
{file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"},
{file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"},
{file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"},
{file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"},
{file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"},
{file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"},
{file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"},
{file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"},
{file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"},
{file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"},
{file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"},
{file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"},
{file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"},
{file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"},
{file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"},
{file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"},
{file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"},
{file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"},
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"},
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"},
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"},
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"},
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"},
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"},
{file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"},
{file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"},
{file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"},
{file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"},
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"},
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"},
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"},
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"},
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"},
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"},
{file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"},
{file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"},
{file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"},
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"},
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"},
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"},
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"},
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"},
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"},
{file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"},
{file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"},
{file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"},
{file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"},
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"},
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"},
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"},
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"},
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"},
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"},
{file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"},
{file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"},
{file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"},
{file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"},
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"},
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"},
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"},
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"},
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"},
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"},
{file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"},
{file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"},
{file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"},
{file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"},
]
[package.extras]
@ -997,13 +988,14 @@ tox = ["tox"]
[[package]]
name = "dacite"
version = "1.8.1"
version = "1.8.0"
description = "Simple creation of data classes from dictionaries."
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "dacite-1.8.1-py3-none-any.whl", hash = "sha256:cc31ad6fdea1f49962ea42db9421772afe01ac5442380d9a99fcf3d188c61afe"},
{file = "dacite-1.8.0-py3-none-any.whl", hash = "sha256:f7b1205cc5d9b62835aac8cbc1e6e37c1da862359a401f1edbe2ae08fbdc6193"},
{file = "dacite-1.8.0.tar.gz", hash = "sha256:6257a5e505b61a8cafee7ef3ad08cf32ee9b885718f42395d017e0a9b4c6af65"},
]
[package.extras]
@ -1136,14 +1128,14 @@ Django = ">=3.2"
[[package]]
name = "django-otp"
version = "1.2.1"
version = "1.2.0"
description = "A pluggable framework for adding two-factor authentication to Django using one-time passwords."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "django_otp-1.2.1-py3-none-any.whl", hash = "sha256:1758aabfc17c30ba00142e823c961e20d2a0353040a9e4e4be2688cf71085446"},
{file = "django_otp-1.2.1.tar.gz", hash = "sha256:d4785291fc97eb61c02574660f7ae82baab04da187fa5d0fb649d57deea2c62e"},
{file = "django_otp-1.2.0-py3-none-any.whl", hash = "sha256:aa14ace751bede7c6c385f2ea3589f6aa3565a31e455fa0ee69801b79761e3b0"},
{file = "django_otp-1.2.0.tar.gz", hash = "sha256:2baa30237f46549446d8d17a790b962f9065168bad38968dd208cdeb85901ede"},
]
[package.dependencies]
@ -1260,14 +1252,14 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"]
[[package]]
name = "docker"
version = "6.1.2"
version = "6.1.1"
description = "A Python library for the Docker Engine API."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "docker-6.1.2-py3-none-any.whl", hash = "sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e"},
{file = "docker-6.1.2.tar.gz", hash = "sha256:dcc088adc2ec4e7cfc594e275d8bd2c9738c56c808de97476939ef67db5af8c2"},
{file = "docker-6.1.1-py3-none-any.whl", hash = "sha256:8308b23d3d0982c74f7aa0a3abd774898c0c4fba006e9c3bde4f68354e470fe2"},
{file = "docker-6.1.1.tar.gz", hash = "sha256:5ec18b9c49d48ee145a5b5824bb126dc32fc77931e18444783fc07a7724badc0"},
]
[package.dependencies]
@ -2271,14 +2263,14 @@ files = [
[[package]]
name = "paramiko"
version = "3.2.0"
version = "3.1.0"
description = "SSH2 protocol library"
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "paramiko-3.2.0-py3-none-any.whl", hash = "sha256:df0f9dd8903bc50f2e10580af687f3015bf592a377cd438d2ec9546467a14eb8"},
{file = "paramiko-3.2.0.tar.gz", hash = "sha256:93cdce625a8a1dc12204439d45033f3261bdb2c201648cfcdc06f9fd0f94ec29"},
{file = "paramiko-3.1.0-py3-none-any.whl", hash = "sha256:f0caa660e797d9cd10db6fc6ae81e2c9b2767af75c3180fcd0e46158cd368d7f"},
{file = "paramiko-3.1.0.tar.gz", hash = "sha256:6950faca6819acd3219d4ae694a23c7a87ee38d084f70c1724b0c0dbb8b75769"},
]
[package.dependencies]
@ -2502,44 +2494,45 @@ files = [
[[package]]
name = "pycryptodome"
version = "3.18.0"
version = "3.17"
description = "Cryptographic library for Python"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "pycryptodome-3.18.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:d1497a8cd4728db0e0da3c304856cb37c0c4e3d0b36fcbabcc1600f18504fc54"},
{file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:928078c530da78ff08e10eb6cada6e0dff386bf3d9fa9871b4bbc9fbc1efe024"},
{file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:157c9b5ba5e21b375f052ca78152dd309a09ed04703fd3721dce3ff8ecced148"},
{file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:d20082bdac9218649f6abe0b885927be25a917e29ae0502eaf2b53f1233ce0c2"},
{file = "pycryptodome-3.18.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:e8ad74044e5f5d2456c11ed4cfd3e34b8d4898c0cb201c4038fe41458a82ea27"},
{file = "pycryptodome-3.18.0-cp27-cp27m-win32.whl", hash = "sha256:62a1e8847fabb5213ccde38915563140a5b338f0d0a0d363f996b51e4a6165cf"},
{file = "pycryptodome-3.18.0-cp27-cp27m-win_amd64.whl", hash = "sha256:16bfd98dbe472c263ed2821284118d899c76968db1a6665ade0c46805e6b29a4"},
{file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:7a3d22c8ee63de22336679e021c7f2386f7fc465477d59675caa0e5706387944"},
{file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:78d863476e6bad2a592645072cc489bb90320972115d8995bcfbee2f8b209918"},
{file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:b6a610f8bfe67eab980d6236fdc73bfcdae23c9ed5548192bb2d530e8a92780e"},
{file = "pycryptodome-3.18.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:422c89fd8df8a3bee09fb8d52aaa1e996120eafa565437392b781abec2a56e14"},
{file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:9ad6f09f670c466aac94a40798e0e8d1ef2aa04589c29faa5b9b97566611d1d1"},
{file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:53aee6be8b9b6da25ccd9028caf17dcdce3604f2c7862f5167777b707fbfb6cb"},
{file = "pycryptodome-3.18.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:10da29526a2a927c7d64b8f34592f461d92ae55fc97981aab5bbcde8cb465bb6"},
{file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f21efb8438971aa16924790e1c3dba3a33164eb4000106a55baaed522c261acf"},
{file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4944defabe2ace4803f99543445c27dd1edbe86d7d4edb87b256476a91e9ffa4"},
{file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:51eae079ddb9c5f10376b4131be9589a6554f6fd84f7f655180937f611cd99a2"},
{file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:83c75952dcf4a4cebaa850fa257d7a860644c70a7cd54262c237c9f2be26f76e"},
{file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:957b221d062d5752716923d14e0926f47670e95fead9d240fa4d4862214b9b2f"},
{file = "pycryptodome-3.18.0-cp35-abi3-win32.whl", hash = "sha256:795bd1e4258a2c689c0b1f13ce9684fa0dd4c0e08680dcf597cf9516ed6bc0f3"},
{file = "pycryptodome-3.18.0-cp35-abi3-win_amd64.whl", hash = "sha256:b1d9701d10303eec8d0bd33fa54d44e67b8be74ab449052a8372f12a66f93fb9"},
{file = "pycryptodome-3.18.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:cb1be4d5af7f355e7d41d36d8eec156ef1382a88638e8032215c215b82a4b8ec"},
{file = "pycryptodome-3.18.0-pp27-pypy_73-win32.whl", hash = "sha256:fc0a73f4db1e31d4a6d71b672a48f3af458f548059aa05e83022d5f61aac9c08"},
{file = "pycryptodome-3.18.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f022a4fd2a5263a5c483a2bb165f9cb27f2be06f2f477113783efe3fe2ad887b"},
{file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363dd6f21f848301c2dcdeb3c8ae5f0dee2286a5e952a0f04954b82076f23825"},
{file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12600268763e6fec3cefe4c2dcdf79bde08d0b6dc1813887e789e495cb9f3403"},
{file = "pycryptodome-3.18.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4604816adebd4faf8810782f137f8426bf45fee97d8427fa8e1e49ea78a52e2c"},
{file = "pycryptodome-3.18.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:01489bbdf709d993f3058e2996f8f40fee3f0ea4d995002e5968965fa2fe89fb"},
{file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3811e31e1ac3069988f7a1c9ee7331b942e605dfc0f27330a9ea5997e965efb2"},
{file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4b967bb11baea9128ec88c3d02f55a3e338361f5e4934f5240afcb667fdaec"},
{file = "pycryptodome-3.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9c8eda4f260072f7dbe42f473906c659dcbadd5ae6159dfb49af4da1293ae380"},
{file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"},
{file = "pycryptodome-3.17-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:2c5631204ebcc7ae33d11c43037b2dafe25e2ab9c1de6448eb6502ac69c19a56"},
{file = "pycryptodome-3.17-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:04779cc588ad8f13c80a060b0b1c9d1c203d051d8a43879117fe6b8aaf1cd3fa"},
{file = "pycryptodome-3.17-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f812d58c5af06d939b2baccdda614a3ffd80531a26e5faca2c9f8b1770b2b7af"},
{file = "pycryptodome-3.17-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:9453b4e21e752df8737fdffac619e93c9f0ec55ead9a45df782055eb95ef37d9"},
{file = "pycryptodome-3.17-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:121d61663267f73692e8bde5ec0d23c9146465a0d75cad75c34f75c752527b01"},
{file = "pycryptodome-3.17-cp27-cp27m-win32.whl", hash = "sha256:ba2d4fcb844c6ba5df4bbfee9352ad5352c5ae939ac450e06cdceff653280450"},
{file = "pycryptodome-3.17-cp27-cp27m-win_amd64.whl", hash = "sha256:87e2ca3aa557781447428c4b6c8c937f10ff215202ab40ece5c13a82555c10d6"},
{file = "pycryptodome-3.17-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f44c0d28716d950135ff21505f2c764498eda9d8806b7c78764165848aa419bc"},
{file = "pycryptodome-3.17-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5a790bc045003d89d42e3b9cb3cc938c8561a57a88aaa5691512e8540d1ae79c"},
{file = "pycryptodome-3.17-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:d086d46774e27b280e4cece8ab3d87299cf0d39063f00f1e9290d096adc5662a"},
{file = "pycryptodome-3.17-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:5587803d5b66dfd99e7caa31ed91fba0fdee3661c5d93684028ad6653fce725f"},
{file = "pycryptodome-3.17-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:e7debd9c439e7b84f53be3cf4ba8b75b3d0b6e6015212355d6daf44ac672e210"},
{file = "pycryptodome-3.17-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ca1ceb6303be1282148f04ac21cebeebdb4152590842159877778f9cf1634f09"},
{file = "pycryptodome-3.17-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:dc22cc00f804485a3c2a7e2010d9f14a705555f67020eb083e833cabd5bd82e4"},
{file = "pycryptodome-3.17-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80ea8333b6a5f2d9e856ff2293dba2e3e661197f90bf0f4d5a82a0a6bc83a626"},
{file = "pycryptodome-3.17-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c133f6721fba313722a018392a91e3c69d3706ae723484841752559e71d69dc6"},
{file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:333306eaea01fde50a73c4619e25631e56c4c61bd0fb0a2346479e67e3d3a820"},
{file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:1a30f51b990994491cec2d7d237924e5b6bd0d445da9337d77de384ad7f254f9"},
{file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:909e36a43fe4a8a3163e9c7fc103867825d14a2ecb852a63d3905250b308a4e5"},
{file = "pycryptodome-3.17-cp35-abi3-win32.whl", hash = "sha256:a3228728a3808bc9f18c1797ec1179a0efb5068c817b2ffcf6bcd012494dffb2"},
{file = "pycryptodome-3.17-cp35-abi3-win_amd64.whl", hash = "sha256:9ec565e89a6b400eca814f28d78a9ef3f15aea1df74d95b28b7720739b28f37f"},
{file = "pycryptodome-3.17-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:e1819b67bcf6ca48341e9b03c2e45b1c891fa8eb1a8458482d14c2805c9616f2"},
{file = "pycryptodome-3.17-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:f8e550caf52472ae9126953415e4fc554ab53049a5691c45b8816895c632e4d7"},
{file = "pycryptodome-3.17-pp27-pypy_73-win32.whl", hash = "sha256:afbcdb0eda20a0e1d44e3a1ad6d4ec3c959210f4b48cabc0e387a282f4c7deb8"},
{file = "pycryptodome-3.17-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a74f45aee8c5cc4d533e585e0e596e9f78521e1543a302870a27b0ae2106381e"},
{file = "pycryptodome-3.17-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38bbd6717eac084408b4094174c0805bdbaba1f57fc250fd0309ae5ec9ed7e09"},
{file = "pycryptodome-3.17-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f68d6c8ea2974a571cacb7014dbaada21063a0375318d88ac1f9300bc81e93c3"},
{file = "pycryptodome-3.17-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8198f2b04c39d817b206ebe0db25a6653bb5f463c2319d6f6d9a80d012ac1e37"},
{file = "pycryptodome-3.17-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3a232474cd89d3f51e4295abe248a8b95d0332d153bf46444e415409070aae1e"},
{file = "pycryptodome-3.17-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4992ec965606054e8326e83db1c8654f0549cdb26fce1898dc1a20bc7684ec1c"},
{file = "pycryptodome-3.17-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53068e33c74f3b93a8158dacaa5d0f82d254a81b1002e0cd342be89fcb3433eb"},
{file = "pycryptodome-3.17-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:74794a2e2896cd0cf56fdc9db61ef755fa812b4a4900fa46c49045663a92b8d0"},
{file = "pycryptodome-3.17.tar.gz", hash = "sha256:bce2e2d8e82fcf972005652371a3e8731956a0c1fbb719cc897943b3695ad91b"},
]
[[package]]
@ -3021,21 +3014,21 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"
[[package]]
name = "requests"
version = "2.31.0"
version = "2.28.1"
description = "Python HTTP for Humans."
category = "main"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.7, <4"
files = [
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
]
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<4"
charset-normalizer = ">=2,<3"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<3"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
@ -3116,29 +3109,29 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.0.270"
version = "0.0.265"
description = "An extremely fast Python linter, written in Rust."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.0.270-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f74c4d550f7b8e808455ac77bbce38daafc458434815ba0bc21ae4bdb276509b"},
{file = "ruff-0.0.270-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:643de865fd35cb76c4f0739aea5afe7b8e4d40d623df7e9e6ea99054e5cead0a"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eca02e709b3308eb7255b5f74e779be23b5980fca3862eae28bb23069cd61ae4"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ed3b198768d2b3a2300fb18f730cd39948a5cc36ba29ae9d4639a11040880be"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:739495d2dbde87cf4e3110c8d27bc20febf93112539a968a4e02c26f0deccd1d"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:08188f8351f4c0b6216e8463df0a76eb57894ca59a3da65e4ed205db980fd3ae"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0827b074635d37984fc98d99316bfab5c8b1231bb83e60dacc83bd92883eedb4"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d61ae4841313f6eeb8292dc349bef27b4ce426e62c36e80ceedc3824e408734"},
{file = "ruff-0.0.270-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0eb412f20e77529a01fb94d578b19dcb8331b56f93632aa0cce4a2ea27b7aeba"},
{file = "ruff-0.0.270-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b775e2c5fc869359daf8c8b8aa0fd67240201ab2e8d536d14a0edf279af18786"},
{file = "ruff-0.0.270-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:21f00e47ab2308617c44435c8dfd9e2e03897461c9e647ec942deb2a235b4cfd"},
{file = "ruff-0.0.270-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0bbfbf6fd2436165566ca85f6e57be03ed2f0a994faf40180cfbb3604c9232ef"},
{file = "ruff-0.0.270-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8af391ef81f7be960be10886a3c1aac0b298bde7cb9a86ec2b05faeb2081ce6b"},
{file = "ruff-0.0.270-py3-none-win32.whl", hash = "sha256:b4c037fe2f75bcd9aed0c89c7c507cb7fa59abae2bd4c8b6fc331a28178655a4"},
{file = "ruff-0.0.270-py3-none-win_amd64.whl", hash = "sha256:0012f9b7dc137ab7f1f0355e3c4ca49b562baf6c9fa1180948deeb6648c52957"},
{file = "ruff-0.0.270-py3-none-win_arm64.whl", hash = "sha256:9613456b0b375766244c25045e353bc8890c856431cd97893c97b10cc93bd28d"},
{file = "ruff-0.0.270.tar.gz", hash = "sha256:95db07b7850b30ebf32b27fe98bc39e0ab99db3985edbbf0754d399eb2f0e690"},
{file = "ruff-0.0.265-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:30ddfe22de6ce4eb1260408f4480bbbce998f954dbf470228a21a9b2c45955e4"},
{file = "ruff-0.0.265-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:a11bd0889e88d3342e7bc514554bb4461bf6cc30ec115821c2425cfaac0b1b6a"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a9b38bdb40a998cbc677db55b6225a6c4fadcf8819eb30695e1b8470942426b"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8b44a245b60512403a6a03a5b5212da274d33862225c5eed3bcf12037eb19bb"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b279fa55ea175ef953208a6d8bfbcdcffac1c39b38cdb8c2bfafe9222add70bb"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5028950f7af9b119d43d91b215d5044976e43b96a0d1458d193ef0dd3c587bf8"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4057eb539a1d88eb84e9f6a36e0a999e0f261ed850ae5d5817e68968e7b89ed9"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d586e69ab5cbf521a1910b733412a5735936f6a610d805b89d35b6647e2a66aa"},
{file = "ruff-0.0.265-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa17b13cd3f29fc57d06bf34c31f21d043735cc9a681203d634549b0e41047d1"},
{file = "ruff-0.0.265-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:9ac13b11d9ad3001de9d637974ec5402a67cefdf9fffc3929ab44c2fcbb850a1"},
{file = "ruff-0.0.265-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:62a9578b48cfd292c64ea3d28681dc16b1aa7445b7a7709a2884510fc0822118"},
{file = "ruff-0.0.265-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0f9967f84da42d28e3d9d9354cc1575f96ed69e6e40a7d4b780a7a0418d9409"},
{file = "ruff-0.0.265-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1d5a8de2fbaf91ea5699451a06f4074e7a312accfa774ad9327cde3e4fda2081"},
{file = "ruff-0.0.265-py3-none-win32.whl", hash = "sha256:9e9db5ccb810742d621f93272e3cc23b5f277d8d00c4a79668835d26ccbe48dd"},
{file = "ruff-0.0.265-py3-none-win_amd64.whl", hash = "sha256:f54facf286103006171a00ce20388d88ed1d6732db3b49c11feb9bf3d46f90e9"},
{file = "ruff-0.0.265-py3-none-win_arm64.whl", hash = "sha256:c78470656e33d32ddc54e8482b1b0fc6de58f1195586731e5ff1405d74421499"},
{file = "ruff-0.0.265.tar.gz", hash = "sha256:53c17f0dab19ddc22b254b087d1381b601b155acfa8feed514f0d6a413d0ab3a"},
]
[[package]]
@ -3161,14 +3154,14 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]}
[[package]]
name = "sentry-sdk"
version = "1.24.0"
version = "1.22.2"
description = "Python client for Sentry (https://sentry.io)"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "sentry-sdk-1.24.0.tar.gz", hash = "sha256:0bbcecda9f51936904c1030e7fef0fe693e633888f02a14d1cb68646a50e83b3"},
{file = "sentry_sdk-1.24.0-py2.py3-none-any.whl", hash = "sha256:56d6d9d194c898d853a7c1dd99bed92ce82334ee1282292c15bcc967ff1a49b5"},
{file = "sentry-sdk-1.22.2.tar.gz", hash = "sha256:5932c092c6e6035584eb74d77064e4bce3b7935dfc4a331349719a40db265840"},
{file = "sentry_sdk-1.22.2-py2.py3-none-any.whl", hash = "sha256:cf89a5063ef84278d186aceaed6fb595bfe67d099298e537634a323664265669"},
]
[package.dependencies]
@ -3185,11 +3178,10 @@ chalice = ["chalice (>=1.16.0)"]
django = ["django (>=1.8)"]
falcon = ["falcon (>=1.4)"]
fastapi = ["fastapi (>=0.79.0)"]
flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
grpcio = ["grpcio (>=1.21.1)"]
httpx = ["httpx (>=0.16.0)"]
huey = ["huey (>=2)"]
loguru = ["loguru (>=0.5)"]
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
pure-eval = ["asttokens", "executing", "pure-eval"]
pymongo = ["pymongo (>=3.1)"]
@ -3385,23 +3377,23 @@ files = [
[[package]]
name = "tornado"
version = "6.3.2"
version = "6.2"
description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
category = "main"
optional = false
python-versions = ">= 3.8"
python-versions = ">= 3.7"
files = [
{file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"},
{file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"},
{file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"},
{file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"},
{file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"},
{file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"},
{file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"},
{file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"},
{file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"},
{file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"},
{file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"},
{file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"},
{file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"},
{file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"},
{file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"},
{file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"},
{file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"},
{file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"},
{file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"},
{file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"},
{file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"},
{file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"},
]
[[package]]
@ -3444,14 +3436,14 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "8.2.1"
version = "8.2.0"
description = "Twilio API client and TwiML generator"
category = "main"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-8.2.1-py2.py3-none-any.whl", hash = "sha256:9c6bbfda1f3196c64258b6661e372c23e2e6a9630c9986f725d16bb4bfe3275f"},
{file = "twilio-8.2.1.tar.gz", hash = "sha256:66fe6a18199955b8abce2699e533b56f605a22d585c3f0b1820113ec068a0b51"},
{file = "twilio-8.2.0-py2.py3-none-any.whl", hash = "sha256:23eceaec183995fc827e3bfad229cca6e1944bfd9604e57e2712e625b6e01223"},
{file = "twilio-8.2.0.tar.gz", hash = "sha256:0c19eb6a5b84dbcd15658e23a142df026297236e4d72ad9304fd95e7dbff2662"},
]
[package.dependencies]
@ -3592,14 +3584,14 @@ files = [
[[package]]
name = "urllib3"
version = "1.26.16"
version = "1.26.15"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
files = [
{file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"},
{file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"},
{file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"},
{file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"},
]
[package.dependencies]

View File

@ -4,8 +4,7 @@ FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
COPY ./web /static/
ENV NODE_ENV=production
WORKDIR /static
RUN npm ci --include=dev && npm run build-proxy
RUN cd /static && npm ci && npm run build-proxy
# Stage 2: Build
FROM docker.io/golang:1.20.4-bullseye AS builder

View File

@ -113,7 +113,7 @@ filterwarnings = [
[tool.poetry]
name = "authentik"
version = "2023.5.2"
version = "2023.4.1"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2023.5.2
version: 2023.4.1
description: Making authentication simple.
contact:
email: hello@goauthentik.io
@ -18450,11 +18450,6 @@ paths:
* `email_deny` - Use the user's email address, but deny enrollment when the email address already exists.
* `username_link` - Link to a user with identical username. Can have security implications when a username is used with another source.
* `username_deny` - Use the user's username, but deny enrollment when the username already exists.
- in: query
name: verification_kp
schema:
type: string
format: uuid
tags:
- sources
security:
@ -37285,20 +37280,13 @@ components:
* `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` - Transient
binding_type:
$ref: '#/components/schemas/BindingTypeEnum'
verification_kp:
type: string
format: uuid
nullable: true
title: Verification Certificate
description: When selected, incoming assertion's Signatures will be validated
against this certificate. To allow unsigned Requests, leave on default.
signing_kp:
type: string
format: uuid
nullable: true
title: Signing Keypair
description: Keypair used to sign outgoing Responses going to the Identity
Provider.
description: Keypair which is used to sign outgoing requests. Leave empty
to disable signing.
digest_algorithm:
$ref: '#/components/schemas/DigestAlgorithmEnum'
signature_algorithm:
@ -38968,11 +38956,6 @@ components:
shared_secret:
type: string
description: Shared secret between clients and server to hash packets.
outpost_set:
type: array
items:
type: string
readOnly: true
required:
- assigned_application_name
- assigned_application_slug
@ -38982,7 +38965,6 @@ components:
- component
- meta_model_name
- name
- outpost_set
- pk
- verbose_name
- verbose_name_plural
@ -39620,20 +39602,13 @@ components:
* `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` - Transient
binding_type:
$ref: '#/components/schemas/BindingTypeEnum'
verification_kp:
type: string
format: uuid
nullable: true
title: Verification Certificate
description: When selected, incoming assertion's Signatures will be validated
against this certificate. To allow unsigned Requests, leave on default.
signing_kp:
type: string
format: uuid
nullable: true
title: Signing Keypair
description: Keypair used to sign outgoing Responses going to the Identity
Provider.
description: Keypair which is used to sign outgoing requests. Leave empty
to disable signing.
digest_algorithm:
$ref: '#/components/schemas/DigestAlgorithmEnum'
signature_algorithm:
@ -39734,20 +39709,13 @@ components:
* `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` - Transient
binding_type:
$ref: '#/components/schemas/BindingTypeEnum'
verification_kp:
type: string
format: uuid
nullable: true
title: Verification Certificate
description: When selected, incoming assertion's Signatures will be validated
against this certificate. To allow unsigned Requests, leave on default.
signing_kp:
type: string
format: uuid
nullable: true
title: Signing Keypair
description: Keypair used to sign outgoing Responses going to the Identity
Provider.
description: Keypair which is used to sign outgoing requests. Leave empty
to disable signing.
digest_algorithm:
$ref: '#/components/schemas/DigestAlgorithmEnum'
signature_algorithm:
@ -39856,11 +39824,11 @@ components:
type: string
description: Get object component so that we know how to edit the object
readOnly: true
assigned_backchannel_application_slug:
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
readOnly: true
assigned_backchannel_application_name:
assigned_application_name:
type: string
description: Application's display Name.
readOnly: true
@ -39889,8 +39857,8 @@ components:
format: uuid
nullable: true
required:
- assigned_backchannel_application_name
- assigned_backchannel_application_slug
- assigned_application_name
- assigned_application_slug
- component
- meta_model_name
- name
@ -41003,6 +40971,7 @@ components:
type: string
required:
- avatar
- groups
- groups_obj
- is_superuser
- name
@ -41460,6 +41429,7 @@ components:
type: string
minLength: 1
required:
- groups
- name
- username
UserSAMLSourceConnection:

View File

@ -243,7 +243,7 @@ class TestSourceOAuth1(SeleniumTestCase):
def get_container_specs(self) -> Optional[dict[str, Any]]:
return {
"image": "ghcr.io/beryju/oauth1-test-server:v1.1",
"image": "ghcr.io/beryju/oauth1-test-server:latest",
"detach": True,
"network_mode": "host",
"auto_remove": True,

2959
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,24 +16,45 @@
"background-image": "npx @squoosh/cli -d src/assets/images --resize '{\"enabled\":true,\"width\":2560,\"method\":\"lanczos3\",\"fitMethod\":\"contain\",\"premultiply\":true,\"linearRGB\":true}' --mozjpeg '{\"quality\":75,\"baseline\":false,\"arithmetic\":false,\"progressive\":true,\"optimize_coding\":true,\"smoothing\":0,\"color_space\":3,\"quant_table\":3,\"trellis_multipass\":false,\"trellis_opt_zero\":false,\"trellis_opt_table\":false,\"trellis_loops\":1,\"auto_subsample\":true,\"chroma_subsample\":2,\"separate_chroma_quality\":false,\"chroma_quality\":75}' src/assets/images/flow_background.jpg"
},
"dependencies": {
"@babel/core": "^7.21.8",
"@babel/plugin-proposal-decorators": "^7.21.0",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/preset-env": "^7.21.5",
"@babel/preset-typescript": "^7.21.5",
"@codemirror/lang-html": "^6.4.3",
"@codemirror/lang-javascript": "^6.1.8",
"@codemirror/lang-javascript": "^6.1.7",
"@codemirror/lang-python": "^6.1.2",
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/legacy-modes": "^6.3.2",
"@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.2.2",
"@fortawesome/fontawesome-free": "^6.4.0",
"@goauthentik/api": "^2023.5.2-1685273038",
"@lingui/cli": "^4.2.0",
"@lingui/core": "^4.2.0",
"@lingui/detect-locale": "^4.2.0",
"@lingui/format-po-gettext": "^4.2.0",
"@lingui/macro": "^4.2.0",
"@goauthentik/api": "^2023.4.1-1683802980",
"@hcaptcha/types": "^1.0.3",
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
"@lingui/cli": "^4.0.0",
"@lingui/core": "^4.0.0",
"@lingui/detect-locale": "^4.0.0",
"@lingui/format-po-gettext": "^4.0.0",
"@lingui/macro": "^4.0.0",
"@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^7.53.1",
"@sentry/tracing": "^7.53.1",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-typescript": "^11.1.0",
"@sentry/browser": "^7.51.2",
"@sentry/tracing": "^7.51.2",
"@squoosh/cli": "^0.7.3",
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/chart.js": "^2.9.37",
"@types/codemirror": "5.60.7",
"@types/grecaptcha": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "^5.59.5",
"@webcomponents/webcomponentsjs": "^2.8.0",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"base64-js": "^1.5.1",
"chart.js": "^4.3.0",
"chartjs-adapter-moment": "^1.0.1",
@ -41,51 +62,27 @@
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.30.2",
"country-flag-icons": "^1.5.7",
"fuse.js": "^6.6.2",
"lit": "^2.7.4",
"mermaid": "^10.2.0",
"rapidoc": "^9.3.4",
"webcomponent-qr-code": "^1.1.1",
"yaml": "^2.3.1"
},
"devDependencies": {
"@babel/core": "^7.22.1",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.22.3",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-transform-runtime": "^7.22.4",
"@babel/preset-env": "^7.22.4",
"@babel/preset-typescript": "^7.21.5",
"@hcaptcha/types": "^1.0.3",
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-typescript": "^11.1.1",
"@squoosh/cli": "^0.7.3",
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/chart.js": "^2.9.37",
"@types/codemirror": "5.60.7",
"@types/grecaptcha": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"eslint": "^8.41.0",
"eslint": "^8.40.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.8",
"eslint-plugin-lit": "^1.8.3",
"fuse.js": "^6.6.2",
"lit": "^2.7.4",
"mermaid": "^10.1.0",
"moment": "^2.29.4",
"prettier": "^2.8.8",
"pyright": "^1.1.310",
"pyright": "^1.1.307",
"rapidoc": "^9.3.4",
"rollup": "^2.79.1",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-cssimport": "^1.0.3",
"rollup-plugin-minify-html-literals": "^1.2.6",
"rollup-plugin-terser": "^7.0.2",
"ts-lit-plugin": "^1.2.1",
"tslib": "^2.5.2",
"tslib": "^2.5.0",
"turnstile-types": "^1.1.2",
"typescript": "^5.0.4"
"typescript": "^5.0.4",
"webcomponent-qr-code": "^1.1.1",
"yaml": "^2.2.2"
}
}

View File

@ -61,10 +61,6 @@ export class ProviderViewPage extends AKElement {
return html`<ak-provider-scim-view
providerID=${ifDefined(this.provider.pk)}
></ak-provider-scim-view>`;
case "ak-provider-radius-form":
return html`<ak-provider-radius-view
providerID=${ifDefined(this.provider.pk)}
></ak-provider-radius-view>`;
default:
return html`<p>Invalid provider type ${this.provider?.component}</p>`;
}

View File

@ -79,11 +79,6 @@ export class RadiusProviderViewPage extends AKElement {
data-tab-title="${t`Overview`}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
${this.provider?.outpostSet.length < 1
? html`<div slot="header" class="pf-c-banner pf-m-warning">
${t`Warning: Provider is not used by any Outpost.`}
</div>`
: html``}
<div class="pf-u-display-flex pf-u-justify-content-center">
<div class="pf-u-w-75">
<div class="pf-c-card">
@ -157,7 +152,7 @@ export class RadiusProviderViewPage extends AKElement {
<ak-object-changelog
targetModelPk=${this.provider.pk || ""}
targetModelApp="authentik_providers_radius"
targetModelName="radiusprovider"
targetModelName="RadiusProvider"
>
</ak-object-changelog>
</div>

View File

@ -121,14 +121,9 @@ export class SCIMProviderViewPage extends AKElement {
if (!this.provider) {
return html``;
}
return html`<div slot="header" class="pf-c-banner pf-m-info">
return html` <div slot="header" class="pf-c-banner pf-m-info">
${t`SCIM provider is in preview.`}
</div>
${!this.provider?.assignedBackchannelApplicationName
? html`<div slot="header" class="pf-c-banner pf-m-warning">
${t`Warning: Provider is not assigned to an application as backchannel provider.`}
</div>`
: html``}
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
<div class="pf-l-grid__item pf-m-7-col pf-l-stack pf-m-gutter">
<div class="pf-c-card pf-m-12-col pf-l-stack__item">

View File

@ -304,42 +304,6 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
${t`Keypair which is used to sign outgoing requests. Leave empty to disable signing.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Verification Certificate`}
name="verificationKp"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.verificationKp;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text">
${t`When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.`}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
<ak-form-group>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 KiB

After

Width:  |  Height:  |  Size: 551 KiB

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2023.5.2";
export const VERSION = "2023.4.1";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -142,10 +142,6 @@ export abstract class Form<T> extends AKElement {
if (element.hidden || !inputElement) {
return;
}
// Skip elements that are writeOnly where the user hasn't clicked on the value
if (element.writeOnly && !element.writeOnlyActivated) {
return;
}
if (
inputElement.tagName.toLowerCase() === "select" &&
"multiple" in inputElement.attributes

View File

@ -525,7 +525,8 @@ export class FlowExecutor extends Interface implements StageHost {
${this.flowInfo?.background?.startsWith("/static")
? html`
<li>
<a href="https://unsplash.com/@joshnh"
<a
href="https://unsplash.com/@clarissemeyer"
>${t`Background image`}</a
>
</li>

View File

@ -39,7 +39,10 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
}
getURL(): string {
return new URL(this.challenge.to, document.baseURI).toString();
if (!this.challenge.to.includes("://")) {
return window.location.origin + this.challenge.to;
}
return this.challenge.to;
}
firstUpdated(): void {

View File

@ -53,10 +53,9 @@ export class AuthenticatorValidateStage
_selectedDeviceChallenge?: DeviceChallenge;
set selectedDeviceChallenge(value: DeviceChallenge | undefined) {
const previousChallenge = this._selectedDeviceChallenge;
this._selectedDeviceChallenge = value;
if (!value) return;
if (value === previousChallenge) return;
if (value === this._selectedDeviceChallenge) return;
// We don't use this.submit here, as we don't want to advance the flow.
// We just want to notify the backend which challenge has been selected.
new FlowsApi(DEFAULT_CONFIG).flowsExecutorSolve({
@ -135,7 +134,7 @@ export class AuthenticatorValidateStage
<small>${t`In case you can't access any other method.`}</small>
</div>`;
case DeviceClassesEnum.Sms:
return html`<i class="fas fa-mobile-alt"></i>
return html`<i class="fas fa-mobile"></i>
<div class="right">
<p>${t`SMS`}</p>
<small>${t`Tokens sent via SMS.`}</small>

View File

@ -7,7 +7,7 @@ import { PasswordManagerPrefill } from "@goauthentik/flow/stages/identification/
import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
@ -37,24 +37,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
showBackButton = false;
static get styles(): CSSResult[] {
return [
PFBase,
PFLogin,
PFForm,
PFFormControl,
PFTitle,
PFButton,
css`
.icon-description {
display: flex;
}
.icon-description i {
font-size: 2em;
padding: 0.25em;
padding-right: 0.5em;
}
`,
];
return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton];
}
render(): TemplateResult {
@ -79,23 +62,13 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
>
</div>
</ak-form-static>
<div class="icon-description">
<i
class="fa ${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
? "fa-key"
: "fa-mobile-alt"}"
aria-hidden="true"
></i>
${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
? html`<p>${t`A code has been sent to you via SMS.`}</p>`
: html`<p>
${t`Open your two-factor authenticator app to view your authentication code.`}
</p>`}
</div>
${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
? html`<p>${t`A code has been sent to you via SMS.`}</p>`
: html``}
<ak-form-element
label="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
? t`Static token`
: t`Authentication code`}"
: t`Code`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})["code"]}
@ -112,7 +85,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
DeviceClassesEnum.Static
? "[0-9a-zA-Z]*"
: "[0-9]*"}"
placeholder="${t`Please enter your code`}"
placeholder="${t`Please enter your Code`}"
autofocus=""
autocomplete="one-time-code"
class="pf-c-form-control"

View File

@ -202,7 +202,7 @@ export class IdentificationStage extends BaseStage<
}
renderInput(): TemplateResult {
let type: "text" | "email" = "text";
let type = "text";
if (!this.challenge?.userFields || this.challenge.userFields.length === 0) {
return html`<p>${t`Select one of the sources below to login.`}</p>`;
}

View File

@ -64,32 +64,32 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
/>`;
case PromptTypeEnum.TextArea:
return html`<textarea
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
>
${prompt.initialValue}</textarea
>`;
value="${prompt.initialValue}"
></textarea>`;
case PromptTypeEnum.TextReadOnly:
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?readonly=${true}
readonly
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.TextAreaReadOnly:
return html`<textarea
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
readonly
>
${prompt.initialValue}</textarea
>`;
value="${prompt.initialValue}"
></textarea>`;
case PromptTypeEnum.Username:
return html`<input
type="text"
@ -186,8 +186,8 @@ ${prompt.initialValue}</textarea
class="pf-c-check__input"
name="${prompt.fieldKey}"
id="${id}"
?checked="${prompt.initialValue === choice}"
?required="${prompt.required}"
checked="${prompt.initialValue === choice}"
required="${prompt.required}"
value="${choice}"
/>
<label class="pf-c-check__label" for=${id}>${choice}</label>
@ -195,7 +195,7 @@ ${prompt.initialValue}</textarea
})}`;
case PromptTypeEnum.AkLocale:
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
<option value="" ?selected=${prompt.initialValue === ""}>
<option value="" ${prompt.initialValue === "" ? "selected" : ""}>
${t`Auto-detect (based on your browser)`}
</option>
${LOCALES.filter((locale) => {
@ -209,7 +209,7 @@ ${prompt.initialValue}</textarea
}).map((locale) => {
return html`<option
value=${locale.code}
?selected=${prompt.initialValue === locale.code}
${prompt.initialValue === locale.code ? "selected" : ""}
>
${locale.code.toUpperCase()} - ${locale.label}
</option>`;

View File

@ -420,7 +420,7 @@ msgstr "Erweiterte Einstellungen"
msgid "Affected model:"
msgstr "Betroffenes Modell:"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alarm"
@ -791,10 +791,6 @@ msgstr "Authentifizierung mit Plex..."
msgid "Authentication"
msgstr "Authentifizierung"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1427,6 +1423,7 @@ msgstr "Schließen"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Code"
@ -4385,7 +4382,7 @@ msgstr "Nicht Sie?"
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Hinweis"
@ -4557,10 +4554,6 @@ msgstr ""
msgid "Open settings"
msgstr "Einstellungen öffnen"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "OpenID-Konfigurations-Aussteller"
@ -4834,11 +4827,8 @@ msgstr "History"
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Bitte geben Sie Ihren Code ein "
@ -7170,8 +7160,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7766,7 +7756,6 @@ msgid "Verification"
msgstr "Überprüfung"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Zertifikat zur Überprüfung"
@ -7825,7 +7814,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Warnung"
@ -7850,10 +7839,6 @@ msgstr "Warnung: Keine Einladungsphase ist an einen Ablauf gebunden. Einladungen
msgid "Warning: Policy is not assigned."
msgstr "Warnung: Keine Richtlinie zugewiesen"
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7862,7 +7847,6 @@ msgstr "Warnung: Der Anbieter wird nicht von einer Anwendung verwendet."
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Warnung: Der Anbieter wird von keinem Outpost verwendet."
@ -7992,7 +7976,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "Wenn diese Option ausgewählt ist, wird ein Passwortfeld auf derselben Seite statt auf einer separaten Seite angezeigt. Dadurch werden Angriffe auf die Aufzählung von Benutzernamen verhindert."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "Wenn diese Option ausgewählt ist, werden die Signaturen eingehender Behauptungen anhand dieses Zertifikats validiert. Um nicht signierte Anfragen zuzulassen, belassen Sie die Standardeinstellung."

View File

@ -401,7 +401,7 @@ msgstr "Advanced settings"
msgid "Affected model:"
msgstr "Affected model:"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alert"
@ -776,10 +776,6 @@ msgstr "Authenticating with Plex..."
msgid "Authentication"
msgstr "Authentication"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr "Authentication code"
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1424,6 +1420,7 @@ msgstr "Close"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Code"
@ -4447,7 +4444,7 @@ msgstr "Not you?"
msgid "Notes"
msgstr "Notes"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Notice"
@ -4627,10 +4624,6 @@ msgstr "Open login"
msgid "Open settings"
msgstr "Open settings"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr "Open your two-factor authenticator app to view your authentication code."
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "OpenID Configuration Issuer"
@ -4926,11 +4919,8 @@ msgstr "Plan history"
msgid "Please enter the code you received via SMS"
msgstr "Please enter the code you received via SMS"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr "Please enter your code"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Please enter your Code"
@ -7328,8 +7318,8 @@ msgstr "Unknown provider type"
msgid "Unknown proxy mode"
msgstr "Unknown proxy mode"
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr "Unknown severity"
@ -7930,7 +7920,6 @@ msgid "Verification"
msgstr "Verification"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Verification Certificate"
@ -7991,7 +7980,7 @@ msgstr "Waiting for authentication..."
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Warning"
@ -8016,10 +8005,6 @@ msgstr "Warning: No invitation stage is bound to any flow. Invitations will not
msgid "Warning: Policy is not assigned."
msgstr "Warning: Policy is not assigned."
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr "Warning: Provider is not assigned to an application as backchannel provider."
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -8028,7 +8013,6 @@ msgstr "Warning: Provider is not used by an Application."
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Warning: Provider is not used by any Outpost."
@ -8165,7 +8149,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "When selected, a password field is shown on the same page instead of a separate page. This prevents username enumeration attacks."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."

View File

@ -398,7 +398,7 @@ msgstr "Configuraciones avanzadas"
msgid "Affected model:"
msgstr "Modelo afectado:"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alerta"
@ -769,10 +769,6 @@ msgstr "Autenticando con Plex..."
msgid "Authentication"
msgstr "Autenticación"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1403,6 +1399,7 @@ msgstr "Cerrar"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Código"
@ -4361,7 +4358,7 @@ msgstr "¿No eres tú?"
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Notificación"
@ -4533,10 +4530,6 @@ msgstr ""
msgid "Open settings"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "Emisor de configuración de OpenID"
@ -4810,11 +4803,8 @@ msgstr "Historial del plan"
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Por favor, introduzca su código"
@ -7146,8 +7136,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7742,7 +7732,6 @@ msgid "Verification"
msgstr "Verificación"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Certificado de verificación"
@ -7801,7 +7790,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Aviso"
@ -7826,10 +7815,6 @@ msgstr "Advertencia: ninguna etapa de invitación está vinculada a ningún fluj
msgid "Warning: Policy is not assigned."
msgstr "Advertencia: la política no está asignada."
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7838,7 +7823,6 @@ msgstr "Advertencia: Una aplicación no utiliza el proveedor."
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Advertencia: ningún puesto avanzado utiliza el proveedor."
@ -7968,7 +7952,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "Cuando se selecciona, se muestra un campo de contraseña en la misma página en lugar de en una página separada. Esto evita ataques de enumeración de nombres de usuario."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "Cuando se selecciona, las firmas de la aserción entrante se validarán con este certificado. Para permitir solicitudes sin firmar, déjelo en el valor predeterminado."

View File

@ -403,7 +403,7 @@ msgstr "Paramètres avancés"
msgid "Affected model:"
msgstr "Modèle affecté :"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alerte"
@ -774,10 +774,6 @@ msgstr "Authentification avec Plex..."
msgid "Authentication"
msgstr "Authentification"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1408,6 +1404,7 @@ msgstr "Fermer"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Code"
@ -4362,7 +4359,7 @@ msgstr "Pas vous ?"
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Note"
@ -4534,10 +4531,6 @@ msgstr ""
msgid "Open settings"
msgstr "Ouvrir les paramètres"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "Émetteur de la configuration OpenID"
@ -4811,11 +4804,8 @@ msgstr "Historique du plan"
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Entrez votre code"
@ -7137,8 +7127,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7733,7 +7723,6 @@ msgid "Verification"
msgstr "Vérification"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Certificat de validation"
@ -7792,7 +7781,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Avertissement"
@ -7817,10 +7806,6 @@ msgstr "Attention : aucune étape dinvitation na été ajoutée à aucun f
msgid "Warning: Policy is not assigned."
msgstr "Avertissement : la politique n'est pas assignée."
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7829,7 +7814,6 @@ msgstr ""
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Attention : ce fournisseur nest utilisé par aucun avant-poste."
@ -7959,7 +7943,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "Si activée, un champ de mot de passe est affiché sur la même page au lieu d'une page séparée. Cela permet d'éviter les attaques par énumération de noms d'utilisateur."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "Si activée, les signatures des assertions entrantes seront validées par rapport à ce certificat. Pour autoriser les requêtes non signées, laissez la valeur par défaut."

View File

@ -402,7 +402,7 @@ msgstr "Zaawansowane ustawienia"
msgid "Affected model:"
msgstr "Model, którego dotyczy problem:"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alert"
@ -773,10 +773,6 @@ msgstr "Uwierzytelnianie z Plex..."
msgid "Authentication"
msgstr "Uwierzytelnianie"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1409,6 +1405,7 @@ msgstr "Zamknij"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Kod"
@ -4369,7 +4366,7 @@ msgstr "Nie ty?"
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Uwaga"
@ -4541,10 +4538,6 @@ msgstr ""
msgid "Open settings"
msgstr "Otwórz ustawienia"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "Wystawca konfiguracji OpenID"
@ -4818,11 +4811,8 @@ msgstr "Historia planu"
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Wprowadź swój kod"
@ -7156,8 +7146,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7752,7 +7742,6 @@ msgid "Verification"
msgstr "Weryfikacja"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Certyfikat weryfikacji"
@ -7811,7 +7800,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Ostrzeżenie"
@ -7836,10 +7825,6 @@ msgstr "Ostrzeżenie: żaden etap zaproszenia nie jest powiązany z żadnym prze
msgid "Warning: Policy is not assigned."
msgstr "Ostrzeżenie: zasada nie jest przypisana."
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7848,7 +7833,6 @@ msgstr "Ostrzeżenie: Dostawca nie jest używany przez aplikację."
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Ostrzeżenie: Dostawca nie jest używany przez żadną placówkę."
@ -7980,7 +7964,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "Po wybraniu pole hasła jest wyświetlane na tej samej stronie zamiast na osobnej stronie. Zapobiega to atakom polegającym na wyliczaniu nazw użytkowników."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "Po wybraniu, przychodzące podpisy asercji będą sprawdzane względem tego certyfikatu. Aby zezwolić na niepodpisane żądania, pozostaw domyślnie."

View File

@ -397,7 +397,7 @@ msgstr ""
msgid "Affected model:"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr ""
@ -768,10 +768,6 @@ msgstr ""
msgid "Authentication"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1412,6 +1408,7 @@ msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr ""
@ -4426,7 +4423,7 @@ msgstr ""
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr ""
@ -4606,10 +4603,6 @@ msgstr ""
msgid "Open settings"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr ""
@ -4896,11 +4889,8 @@ msgstr ""
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr ""
@ -7286,8 +7276,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7888,7 +7878,6 @@ msgid "Verification"
msgstr ""
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr ""
@ -7949,7 +7938,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr ""
@ -7974,10 +7963,6 @@ msgstr ""
msgid "Warning: Policy is not assigned."
msgstr ""
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7986,7 +7971,6 @@ msgstr ""
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr ""
@ -8117,7 +8101,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr ""
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr ""

View File

@ -398,7 +398,7 @@ msgstr "Gelişmiş ayarlar"
msgid "Affected model:"
msgstr "Etkilenen model:"
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alarm"
@ -769,10 +769,6 @@ msgstr "Plex ile kimlik doğrulaması..."
msgid "Authentication"
msgstr "Kimlik Doğrulama"
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Authentication code"
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
#: src/admin/providers/proxy/ProxyProviderForm.ts
#: src/admin/providers/radius/RadiusProviderForm.ts
@ -1403,6 +1399,7 @@ msgstr "Kapat"
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
msgstr "Kodu"
@ -4361,7 +4358,7 @@ msgstr "Sen değil mi?"
msgid "Notes"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Uyarı"
@ -4533,10 +4530,6 @@ msgstr ""
msgid "Open settings"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Open your two-factor authenticator app to view your authentication code."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "OpenID Yapılandırması Yayımlayıcı"
@ -4810,11 +4803,8 @@ msgstr "Plan geçmişi"
msgid "Please enter the code you received via SMS"
msgstr ""
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your code"
msgstr ""
#: src/flow/providers/oauth2/DeviceCode.ts
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Lütfen Kodunuzu girin"
@ -7146,8 +7136,8 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/utils.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
@ -7742,7 +7732,6 @@ msgid "Verification"
msgstr "Doğrulama"
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "Verification Certificate"
msgstr "Doğrulama Sertifikası"
@ -7801,7 +7790,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/utils.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Uyarı"
@ -7826,10 +7815,6 @@ msgstr "Uyarı: Hiçbir davetiye aşaması herhangi bir akışa bağlı değildi
msgid "Warning: Policy is not assigned."
msgstr "Uyarı: İlke atanmamış."
#: src/admin/providers/scim/SCIMProviderViewPage.ts
msgid "Warning: Provider is not assigned to an application as backchannel provider."
msgstr ""
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/saml/SAMLProviderViewPage.ts
@ -7838,7 +7823,6 @@ msgstr "Uyarı: Sağlayıcı bir Uygulama tarafından kullanılmaz."
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
#: src/admin/providers/radius/RadiusProviderViewPage.ts
msgid "Warning: Provider is not used by any Outpost."
msgstr "Uyarı: Sağlayıcı herhangi bir Üs tarafından kullanılmaz."
@ -7968,7 +7952,6 @@ msgid "When selected, a password field is shown on the same page instead of a se
msgstr "Seçildiğinde, ayrı bir sayfa yerine aynı sayfada bir parola alanı gösterilir. Bu, kullanıcı adı numaralandırma saldırılarını engeller."
#: src/admin/providers/saml/SAMLProviderForm.ts
#: src/admin/sources/saml/SAMLSourceForm.ts
msgid "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
msgstr "Seçildiğinde, gelen onaylama öğesinin İmzaları bu sertifikaya göre doğrulanır. İmzasız İsteklere izin vermek için varsayılan olarak bırakın."

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More