Compare commits

..

5 Commits

Author SHA1 Message Date
36e418436b Revert "Revert "core: applications api: add option to only list apps with launch url (#10336)""
This reverts commit 1eb9d7a9d6.
2024-07-04 12:58:29 +02:00
8b0058ada0 detect RAC differently
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-07-04 12:58:25 +02:00
3abf1421a2 return full URL when possible
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-07-04 12:57:56 +02:00
70c7454c69 return authentik launch URL
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-07-04 12:52:26 +02:00
1eb9d7a9d6 Revert "core: applications api: add option to only list apps with launch url (#10336)"
This reverts commit 42e0ff6492.
2024-07-04 12:50:46 +02:00
543 changed files with 6008 additions and 13352 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.6.1
current_version = 2024.6.0
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -54,10 +54,9 @@ runs:
authentik:
outposts:
container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
image:
repository: ghcr.io/goauthentik/dev-server
tag: ${{ inputs.tag }}
image:
repository: ghcr.io/goauthentik/dev-server
tag: ${{ inputs.tag }}
```
For arm64, use these values:
@ -66,10 +65,9 @@ runs:
authentik:
outposts:
container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
image:
repository: ghcr.io/goauthentik/dev-server
tag: ${{ inputs.tag }}-arm64
image:
repository: ghcr.io/goauthentik/dev-server
tag: ${{ inputs.tag }}-arm64
```
Afterwards, run the upgrade commands from the latest release notes.

View File

@ -21,10 +21,7 @@ updates:
labels:
- dependencies
- package-ecosystem: npm
directories:
- "/web"
- "/tests/wdio"
- "/web/sfe"
directory: "/web"
schedule:
interval: daily
time: "04:00"
@ -33,6 +30,7 @@ updates:
open-pull-requests-limit: 10
commit-message:
prefix: "web:"
# TODO: deduplicate these groups
groups:
sentry:
patterns:
@ -58,6 +56,38 @@ updates:
patterns:
- "@rollup/*"
- "rollup-*"
- package-ecosystem: npm
directory: "/tests/wdio"
schedule:
interval: daily
time: "04:00"
labels:
- dependencies
open-pull-requests-limit: 10
commit-message:
prefix: "web:"
# TODO: deduplicate these groups
groups:
sentry:
patterns:
- "@sentry/*"
- "@spotlightjs/*"
babel:
patterns:
- "@babel/*"
- "babel-*"
eslint:
patterns:
- "@typescript-eslint/*"
- "eslint"
- "eslint-*"
storybook:
patterns:
- "@storybook/*"
- "*storybook*"
esbuild:
patterns:
- "@esbuild/*"
wdio:
patterns:
- "@wdio/*"

View File

@ -31,12 +31,7 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
- name: Upgrade /web
working-directory: web
run: |
export VERSION=`node -e 'console.log(require("../gen-ts-api/package.json").version)'`
npm i @goauthentik/api@$VERSION
- name: Upgrade /web/sfe
working-directory: web/sfe
working-directory: web/
run: |
export VERSION=`node -e 'console.log(require("../gen-ts-api/package.json").version)'`
npm i @goauthentik/api@$VERSION

View File

@ -219,7 +219,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.1.0
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables

View File

@ -76,7 +76,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.1.0
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables

View File

@ -26,10 +26,6 @@ jobs:
- web
- tests/wdio
include:
- command: tsc
project: web
extra_setup: |
cd sfe/ && npm ci
- command: lit-analyse
project: web
extra_setup: |

View File

@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.1.0
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables
@ -68,7 +68,7 @@ jobs:
with:
go-version-file: "go.mod"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.1.0
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables

View File

@ -30,12 +30,8 @@ WORKDIR /work/web
RUN --mount=type=bind,target=/work/web/package.json,src=./web/package.json \
--mount=type=bind,target=/work/web/package-lock.json,src=./web/package-lock.json \
--mount=type=bind,target=/work/web/sfe/package.json,src=./web/sfe/package.json \
--mount=type=bind,target=/work/web/sfe/package-lock.json,src=./web/sfe/package-lock.json \
--mount=type=bind,target=/work/web/scripts,src=./web/scripts \
--mount=type=cache,id=npm-web,sharing=shared,target=/root/.npm \
npm ci --include=dev && \
cd sfe && \
npm ci --include=dev
COPY ./package.json /work
@ -43,9 +39,7 @@ COPY ./web /work/web/
COPY ./website /work/website/
COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
RUN npm run build && \
cd sfe && \
npm run build
RUN npm run build
# Stage 3: Build go proxy
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS go-builder

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2024.6.1"
__version__ = "2024.6.0"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -24,7 +24,7 @@ from authentik.tenants.utils import get_current_tenant
class FooterLinkSerializer(PassiveSerializer):
"""Links returned in Config API"""
href = CharField(read_only=True, allow_null=True)
href = CharField(read_only=True)
name = CharField(read_only=True)

View File

@ -7,7 +7,9 @@ from datetime import timedelta
from django.core.cache import cache
from django.db.models import QuerySet
from django.db.models.functions import ExtractHour
from django.http import HttpRequest
from django.shortcuts import get_object_or_404
from django.urls import reverse
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from guardian.shortcuts import get_objects_for_user
@ -65,10 +67,16 @@ class ApplicationSerializer(ModelSerializer):
def get_launch_url(self, app: Application) -> str | None:
"""Allow formatting of launch URL"""
user = None
rel_url = reverse(
"authentik_core:application-launch",
kwargs={
"application_slug": app.slug,
},
)
if "request" in self.context:
user = self.context["request"].user
return app.get_launch_url(user)
request: HttpRequest = self.context["request"]
return request.build_absolute_uri(rel_url)
return rel_url
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
@ -147,6 +155,13 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
applications.append(application)
return applications
def _filter_applications_with_launch_url(self, pagined_apps: Iterator[Application]) -> list[Application]:
applications = []
for app in pagined_apps:
if app.get_launch_url():
applications.append(app)
return applications
@extend_schema(
parameters=[
OpenApiParameter(
@ -204,6 +219,11 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
location=OpenApiParameter.QUERY,
type=OpenApiTypes.INT,
),
OpenApiParameter(
name="only_with_launch_url",
location=OpenApiParameter.QUERY,
type=OpenApiTypes.BOOL,
),
]
)
def list(self, request: Request) -> Response:
@ -216,6 +236,8 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
if superuser_full_list and request.user.is_superuser:
return super().list(request)
only_with_launch_url = str(request.query_params.get("only_with_launch_url", "false")).lower()
queryset = self._filter_queryset_for_list(self.get_queryset())
paginator: Pagination = self.paginator
paginated_apps = paginator.paginate_queryset(queryset, request)
@ -251,6 +273,10 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
allowed_applications,
timeout=86400,
)
if only_with_launch_url == "true":
allowed_applications = self._filter_applications_with_launch_url(allowed_applications)
serializer = self.get_serializer(allowed_applications, many=True)
return self.get_paginated_response(serializer.data)

View File

@ -7,13 +7,12 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def backport_is_backchannel(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
from authentik.providers.ldap.models import LDAPProvider
from authentik.providers.scim.models import SCIMProvider
for model in [LDAPProvider, SCIMProvider]:
try:
for obj in model.objects.using(db_alias).only("is_backchannel"):
for obj in model.objects.only("is_backchannel"):
obj.is_backchannel = True
obj.save()
except (DatabaseError, InternalError, ProgrammingError):

View File

@ -1,6 +1,7 @@
"""authentik core models"""
from datetime import datetime
from functools import lru_cache
from hashlib import sha256
from typing import Any, Optional, Self
from uuid import uuid4
@ -475,6 +476,10 @@ class Application(SerializerModel, PolicyBindingModel):
return self.meta_icon.name
return self.meta_icon.url
# maxsize is set as 2 since that is called once to check
# if we should return applications with a launch URL
# and a second time to actually get the launch_url
@lru_cache(maxsize=2)
def get_launch_url(self, user: Optional["User"] = None) -> str | None:
"""Get launch URL if set, otherwise attempt to get launch URL based on provider."""
url = None

View File

@ -212,7 +212,7 @@ class SourceFlowManager:
def _prepare_flow(
self,
flow: Flow | None,
flow: Flow,
connection: UserSourceConnection,
stages: list[StageView] | None = None,
**kwargs,
@ -309,9 +309,7 @@ class SourceFlowManager:
# When request isn't authenticated we jump straight to auth
if not self.request.user.is_authenticated:
return self.handle_auth(connection)
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
return self._prepare_flow(None, connection)
connection.save()
# Connection has already been saved
Event.new(
EventAction.SOURCE_LINKED,
message="Linked Source",

View File

@ -10,7 +10,7 @@
versionSubdomain: "{{ version_subdomain }}",
build: "{{ build }}",
};
window.addEventListener("DOMContentLoaded", function () {
window.addEventListener("DOMContentLoaded", () => {
{% for message in messages %}
window.dispatchEvent(
new CustomEvent("ak-message", {

View File

@ -71,9 +71,9 @@
</li>
{% endfor %}
<li>
<span>
<a rel="noopener noreferrer" target="_blank" href="https://goauthentik.io?utm_source=authentik">
{% trans 'Powered by authentik' %}
</span>
</a>
</li>
</ul>
</footer>

View File

@ -20,9 +20,8 @@ from authentik.core.api.transactional_applications import TransactionalApplicati
from authentik.core.api.users import UserViewSet
from authentik.core.views import apps
from authentik.core.views.debug import AccessDeniedView
from authentik.core.views.interface import InterfaceView
from authentik.core.views.interface import FlowInterfaceView, InterfaceView
from authentik.core.views.session import EndSessionView
from authentik.flows.views.interface import FlowInterfaceView
from authentik.root.asgi_middleware import SessionMiddleware
from authentik.root.messages.consumer import MessageConsumer
from authentik.root.middleware import ChannelsLoggingMiddleware
@ -54,8 +53,6 @@ urlpatterns = [
),
path(
"if/flow/<slug:flow_slug>/",
# FIXME: move this url to the flows app...also will cause all
# of the reverse calls to be adjusted
ensure_csrf_cookie(FlowInterfaceView.as_view()),
name="if-flow",
),

View File

@ -8,6 +8,7 @@ from django.views import View
from authentik.core.models import Application
from authentik.flows.challenge import (
ChallengeResponse,
ChallengeTypes,
HttpChallengeResponse,
RedirectChallenge,
)
@ -73,6 +74,7 @@ class RedirectToAppStage(ChallengeStageView):
raise Http404
return RedirectChallenge(
instance={
"type": ChallengeTypes.REDIRECT.value,
"to": launch,
}
)

View File

@ -3,6 +3,7 @@
from json import dumps
from typing import Any
from django.shortcuts import get_object_or_404
from django.views.generic.base import TemplateView
from rest_framework.request import Request
@ -10,6 +11,7 @@ from authentik import get_build_hash
from authentik.admin.tasks import LOCAL_VERSION
from authentik.api.v3.config import ConfigView
from authentik.brands.api import CurrentBrandSerializer
from authentik.flows.models import Flow
class InterfaceView(TemplateView):
@ -23,3 +25,14 @@ class InterfaceView(TemplateView):
kwargs["build"] = get_build_hash()
kwargs["url_kwargs"] = self.kwargs
return super().get_context_data(**kwargs)
class FlowInterfaceView(InterfaceView):
"""Flow interface"""
template_name = "if/flow.html"
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
kwargs["flow"] = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
kwargs["inspector"] = "inspector" in self.request.GET
return super().get_context_data(**kwargs)

View File

@ -32,6 +32,14 @@ class FlowLayout(models.TextChoices):
SIDEBAR_RIGHT = "sidebar_right"
class ChallengeTypes(Enum):
"""Currently defined challenge types"""
NATIVE = "native"
SHELL = "shell"
REDIRECT = "redirect"
class ErrorDetailSerializer(PassiveSerializer):
"""Serializer for rest_framework's error messages"""
@ -52,6 +60,9 @@ class Challenge(PassiveSerializer):
"""Challenge that gets sent to the client based on which stage
is currently active"""
type = ChoiceField(
choices=[(x.value, x.name) for x in ChallengeTypes],
)
flow_info = ContextualFlowInfo(required=False)
component = CharField(default="")
@ -85,6 +96,7 @@ class FlowErrorChallenge(Challenge):
"""Challenge class when an unhandled error occurs during a stage. Normal users
are shown an error message, superusers are shown a full stacktrace."""
type = CharField(default=ChallengeTypes.NATIVE.value)
component = CharField(default="ak-stage-flow-error")
request_id = CharField()

View File

@ -21,9 +21,7 @@ def set_oobe_flow_authentication(apps: Apps, schema_editor: BaseDatabaseSchemaEd
pass
if users.exists():
Flow.objects.using(db_alias).filter(slug="initial-setup").update(
authentication="require_superuser"
)
Flow.objects.filter(slug="initial-setup").update(authentication="require_superuser")
class Migration(migrations.Migration):

View File

@ -18,6 +18,7 @@ from authentik.flows.challenge import (
AccessDeniedChallenge,
Challenge,
ChallengeResponse,
ChallengeTypes,
ContextualFlowInfo,
HttpChallengeResponse,
RedirectChallenge,
@ -243,6 +244,7 @@ class AccessDeniedChallengeView(ChallengeStageView):
return AccessDeniedChallenge(
data={
"error_message": str(self.error_message or "Unknown error"),
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-access-denied",
}
)
@ -262,6 +264,7 @@ class RedirectStage(ChallengeStageView):
)
return RedirectChallenge(
data={
"type": ChallengeTypes.REDIRECT.value,
"to": destination,
}
)

View File

@ -1,54 +0,0 @@
{% load static %}
{% load i18n %}
{% load authentik_core %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
<link rel="icon" href="{{ brand.branding_favicon }}">
<link rel="shortcut icon" href="{{ brand.branding_favicon }}">
{% block head_before %}
{% endblock %}
<link rel="stylesheet" type="text/css" href="{% static 'dist/sfe/bootstrap.min.css' %}">
<meta name="sentry-trace" content="{{ sentry_trace }}" />
{% include "base/header_js.html" %}
<style>
html,
body {
height: 100%;
}
body {
background-image: url("{{ flow.background_url }}");
background-repeat: no-repeat;
background-size: cover;
}
.card {
padding: 3rem;
}
.form-signin {
max-width: 330px;
padding: 1rem;
}
.form-signin .form-floating:focus-within {
z-index: 2;
}
.brand-icon {
max-width: 100%;
}
</style>
</head>
<body class="d-flex align-items-center py-4 bg-body-tertiary">
<div class="card m-auto">
<main class="form-signin w-100 m-auto" id="flow-sfe-container">
</main>
<span class="mt-3 mb-0 text-muted text-center">{% trans 'Powered by authentik' %}</span>
</div>
<script src="{% static 'dist/sfe/index.js' %}"></script>
</body>
</html>

View File

@ -8,6 +8,7 @@ from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.models import User
from authentik.flows.challenge import ChallengeTypes
from authentik.flows.models import Flow
@ -25,6 +26,7 @@ class FlowTestCase(APITestCase):
self.assertEqual(response.status_code, 200)
raw_response = loads(response.content.decode())
self.assertIsNotNone(raw_response["component"])
self.assertIsNotNone(raw_response["type"])
if flow:
self.assertIn("flow_info", raw_response)
self.assertEqual(raw_response["flow_info"]["background"], flow.background_url)
@ -44,4 +46,6 @@ class FlowTestCase(APITestCase):
def assertStageRedirects(self, response: HttpResponse, to: str) -> dict[str, Any]:
"""Wrapper around assertStageResponse that checks for a redirect"""
return self.assertStageResponse(response, component="xak-flow-redirect", to=to)
return self.assertStageResponse(
response, component="xak-flow-redirect", to=to, type=ChallengeTypes.REDIRECT.value
)

View File

@ -2,7 +2,7 @@
from django.test import TestCase
from authentik.flows.challenge import AutosubmitChallenge
from authentik.flows.challenge import AutosubmitChallenge, ChallengeTypes
class TestChallenges(TestCase):
@ -12,6 +12,7 @@ class TestChallenges(TestCase):
"""Test blank autosubmit"""
challenge = AutosubmitChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"url": "http://localhost",
"attrs": {},
}
@ -20,6 +21,7 @@ class TestChallenges(TestCase):
# Test with an empty value
challenge = AutosubmitChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"url": "http://localhost",
"attrs": {"foo": ""},
}

View File

@ -7,6 +7,7 @@ from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.challenge import ChallengeTypes
from authentik.flows.models import FlowDesignation, FlowStageBinding, InvalidResponseAction
from authentik.stages.dummy.models import DummyStage
from authentik.stages.identification.models import IdentificationStage, UserFields
@ -45,7 +46,6 @@ class TestFlowInspector(APITestCase):
self.assertJSONEqual(
res.content,
{
"allow_show_password": False,
"component": "ak-stage-identification",
"flow_info": {
"background": flow.background_url,
@ -54,6 +54,7 @@ class TestFlowInspector(APITestCase):
"layout": "stacked",
},
"flow_designation": "authentication",
"type": ChallengeTypes.NATIVE.value,
"password_fields": False,
"primary_action": "Log in",
"sources": [],

View File

@ -30,6 +30,7 @@ from authentik.flows.apps import HIST_FLOW_EXECUTION_STAGE_TIME
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
FlowErrorChallenge,
HttpChallengeResponse,
RedirectChallenge,
@ -551,6 +552,7 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
return HttpChallengeResponse(
RedirectChallenge(
{
"type": ChallengeTypes.REDIRECT,
"to": str(redirect_url),
}
)
@ -559,6 +561,7 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
return HttpChallengeResponse(
ShellChallenge(
{
"type": ChallengeTypes.SHELL,
"body": source.render().content.decode("utf-8"),
}
)
@ -568,6 +571,7 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
return HttpChallengeResponse(
ShellChallenge(
{
"type": ChallengeTypes.SHELL,
"body": source.content.decode("utf-8"),
}
)

View File

@ -1,41 +0,0 @@
"""Interface views"""
from typing import Any
from django.shortcuts import get_object_or_404
from ua_parser.user_agent_parser import Parse
from authentik.core.views.interface import InterfaceView
from authentik.flows.models import Flow
class FlowInterfaceView(InterfaceView):
"""Flow interface"""
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
kwargs["flow"] = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
kwargs["inspector"] = "inspector" in self.request.GET
return super().get_context_data(**kwargs)
def compat_needs_sfe(self) -> bool:
"""Check if we need to use the simplified flow executor for compatibility"""
ua = Parse(self.request.META.get("HTTP_USER_AGENT", ""))
if ua["user_agent"]["family"] == "IE":
return True
# Only use SFE for Edge 18 and older, after Edge 18 MS switched to chromium which supports
# the default flow executor
if (
ua["user_agent"]["family"] == "Edge"
and int(ua["user_agent"]["major"]) <= 18 # noqa: PLR2004
): # noqa: PLR2004
return True
# https://github.com/AzureAD/microsoft-authentication-library-for-objc
# Used by Microsoft Teams/Office on macOS, and also uses a very outdated browser engine
if "PKeyAuth" in ua["string"]:
return True
return False
def get_template_names(self) -> list[str]:
if self.compat_needs_sfe() or "sfe" in self.request.GET:
return ["if/flow-sfe.html"]
return ["if/flow.html"]

View File

@ -2,7 +2,6 @@ from collections.abc import Callable
from django.core.paginator import Paginator
from django.db.models import Model
from django.db.models.query import Q
from django.db.models.signals import m2m_changed, post_save, pre_delete
from authentik.core.models import Group, User
@ -35,9 +34,7 @@ def register_signals(
def model_post_save(sender: type[Model], instance: User | Group, created: bool, **_):
"""Post save handler"""
if not provider_type.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
).exists():
if not provider_type.objects.filter(backchannel_application__isnull=False).exists():
return
task_sync_direct.delay(class_to_path(instance.__class__), instance.pk, Direction.add.value)
@ -46,9 +43,7 @@ def register_signals(
def model_pre_delete(sender: type[Model], instance: User | Group, **_):
"""Pre-delete handler"""
if not provider_type.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
).exists():
if not provider_type.objects.filter(backchannel_application__isnull=False).exists():
return
task_sync_direct.delay(
class_to_path(instance.__class__), instance.pk, Direction.remove.value
@ -63,9 +58,7 @@ def register_signals(
"""Sync group membership"""
if action not in ["post_add", "post_remove"]:
return
if not provider_type.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
).exists():
if not provider_type.objects.filter(backchannel_application__isnull=False).exists():
return
# reverse: instance is a Group, pk_set is a list of user pks
# non-reverse: instance is a User, pk_set is a list of groups

View File

@ -5,7 +5,6 @@ from celery.exceptions import Retry
from celery.result import allow_join_result
from django.core.paginator import Paginator
from django.db.models import Model, QuerySet
from django.db.models.query import Q
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from structlog.stdlib import BoundLogger, get_logger
@ -38,9 +37,7 @@ class SyncTasks:
self._provider_model = provider_model
def sync_all(self, single_sync: Callable[[int], None]):
for provider in self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
):
for provider in self._provider_model.objects.filter(backchannel_application__isnull=False):
self.trigger_single_task(provider, single_sync)
def trigger_single_task(self, provider: OutgoingSyncProvider, sync_task: Callable[[int], None]):
@ -65,8 +62,7 @@ class SyncTasks:
provider_pk=provider_pk,
)
provider = self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False),
pk=provider_pk,
pk=provider_pk, backchannel_application__isnull=False
).first()
if not provider:
return
@ -208,9 +204,7 @@ class SyncTasks:
if not instance:
return
operation = Direction(raw_op)
for provider in self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
):
for provider in self._provider_model.objects.filter(backchannel_application__isnull=False):
client = provider.client_for_model(instance.__class__)
# Check if the object is allowed within the provider's restrictions
queryset = provider.get_object_qs(instance.__class__)
@ -239,9 +233,7 @@ class SyncTasks:
group = Group.objects.filter(pk=group_pk).first()
if not group:
return
for provider in self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
):
for provider in self._provider_model.objects.filter(backchannel_application__isnull=False):
# Check if the object is allowed within the provider's restrictions
queryset: QuerySet = provider.get_object_qs(Group)
# The queryset we get from the provider must include the instance we've got given

View File

@ -20,7 +20,6 @@ from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSeri
from authentik.core.models import Provider
from authentik.enterprise.license import LicenseKey
from authentik.enterprise.providers.rac.models import RACProvider
from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
from authentik.outposts.apps import MANAGED_OUTPOST, MANAGED_OUTPOST_NAME
from authentik.outposts.models import (
@ -50,10 +49,6 @@ class OutpostSerializer(ModelSerializer):
service_connection_obj = ServiceConnectionSerializer(
source="service_connection", read_only=True
)
refresh_interval_s = SerializerMethodField()
def get_refresh_interval_s(self, obj: Outpost) -> int:
return int(timedelta_from_string(obj.config.refresh_interval).total_seconds())
def validate_name(self, name: str) -> str:
"""Validate name (especially for embedded outpost)"""
@ -89,8 +84,7 @@ class OutpostSerializer(ModelSerializer):
def validate_config(self, config) -> dict:
"""Check that the config has all required fields"""
try:
parsed = from_dict(OutpostConfig, config)
timedelta_string_validator(parsed.refresh_interval)
from_dict(OutpostConfig, config)
except DaciteError as exc:
raise ValidationError(f"Failed to validate config: {str(exc)}") from exc
return config
@ -105,7 +99,6 @@ class OutpostSerializer(ModelSerializer):
"providers_obj",
"service_connection",
"service_connection_obj",
"refresh_interval_s",
"token_identifier",
"config",
"managed",

View File

@ -13,17 +13,16 @@ import authentik.outposts.models
def fix_missing_token_identifier(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
User = apps.get_model("authentik_core", "User")
Token = apps.get_model("authentik_core", "Token")
from authentik.outposts.models import Outpost
for outpost in Outpost.objects.using(db_alias).all().only("pk"):
for outpost in Outpost.objects.using(schema_editor.connection.alias).all().only("pk"):
user_identifier = outpost.user_identifier
users = User.objects.using(db_alias).filter(username=user_identifier)
users = User.objects.filter(username=user_identifier)
if not users.exists():
continue
tokens = Token.objects.using(db_alias).filter(user=users.first())
tokens = Token.objects.filter(user=users.first())
for token in tokens:
if token.identifier != outpost.token_identifier:
token.identifier = outpost.token_identifier
@ -38,8 +37,8 @@ def migrate_to_service_connection(apps: Apps, schema_editor: BaseDatabaseSchemaE
"authentik_outposts", "KubernetesServiceConnection"
)
docker = DockerServiceConnection.objects.using(db_alias).filter(local=True).first()
k8s = KubernetesServiceConnection.objects.using(db_alias).filter(local=True).first()
docker = DockerServiceConnection.objects.filter(local=True).first()
k8s = KubernetesServiceConnection.objects.filter(local=True).first()
try:
for outpost in Outpost.objects.using(db_alias).all().exclude(deployment_type="custom"):
@ -55,21 +54,21 @@ def migrate_to_service_connection(apps: Apps, schema_editor: BaseDatabaseSchemaE
def remove_pb_prefix_users(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
alias = schema_editor.connection.alias
User = apps.get_model("authentik_core", "User")
Outpost = apps.get_model("authentik_outposts", "Outpost")
for outpost in Outpost.objects.using(db_alias).all():
matching = User.objects.using(db_alias).filter(username=f"pb-outpost-{outpost.uuid.hex}")
for outpost in Outpost.objects.using(alias).all():
matching = User.objects.using(alias).filter(username=f"pb-outpost-{outpost.uuid.hex}")
if matching.exists():
matching.delete()
def update_config_prefix(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
alias = schema_editor.connection.alias
Outpost = apps.get_model("authentik_outposts", "Outpost")
for outpost in Outpost.objects.using(db_alias).all():
for outpost in Outpost.objects.using(alias).all():
config = outpost._config
for key in list(config):
if "passbook" in key:

View File

@ -61,7 +61,6 @@ class OutpostConfig:
log_level: str = CONFIG.get("log_level")
object_naming_template: str = field(default="ak-outpost-%(name)s")
refresh_interval: str = "minutes=5"
container_image: str | None = field(default=None)

View File

@ -10,6 +10,7 @@ from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.events.models import Event, EventAction
from authentik.flows.challenge import ChallengeTypes
from authentik.lib.generators import generate_id
from authentik.lib.utils.time import timedelta_from_string
from authentik.providers.oauth2.constants import TOKEN_TYPE
@ -326,6 +327,7 @@ class TestAuthorize(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
@ -395,6 +397,7 @@ class TestAuthorize(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": (
f"http://localhost#access_token={token.token}"
f"&id_token={provider.encode(token.id_token.to_dict())}"
@ -457,6 +460,7 @@ class TestAuthorize(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": (f"http://localhost#code={code.code}" f"&state={state}"),
},
)
@ -512,6 +516,7 @@ class TestAuthorize(OAuthTestCase):
response.content.decode(),
{
"component": "ak-stage-autosubmit",
"type": ChallengeTypes.NATIVE.value,
"url": "http://localhost",
"title": f"Redirecting to {app.name}...",
"attrs": {
@ -559,6 +564,7 @@ class TestAuthorize(OAuthTestCase):
response.content.decode(),
{
"component": "ak-stage-autosubmit",
"type": ChallengeTypes.NATIVE.value,
"url": "http://localhost",
"title": f"Redirecting to {app.name}...",
"attrs": {

View File

@ -8,6 +8,7 @@ from django.urls import reverse
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.challenge import ChallengeTypes
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.constants import GRANT_TYPE_AUTHORIZATION_CODE
from authentik.providers.oauth2.models import AuthorizationCode, OAuth2Provider
@ -59,6 +60,7 @@ class TestTokenPKCE(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
@ -121,6 +123,7 @@ class TestTokenPKCE(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
@ -188,6 +191,7 @@ class TestTokenPKCE(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
@ -238,6 +242,7 @@ class TestTokenPKCE(OAuthTestCase):
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)

View File

@ -22,6 +22,7 @@ from authentik.events.signals import get_login_event
from authentik.flows.challenge import (
PLAN_CONTEXT_TITLE,
AutosubmitChallenge,
ChallengeTypes,
HttpChallengeResponse,
)
from authentik.flows.exceptions import FlowNonApplicableException
@ -483,6 +484,7 @@ class OAuthFulfillmentStage(StageView):
challenge = AutosubmitChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-autosubmit",
"title": self.executor.plan.context.get(
PLAN_CONTEXT_TITLE,

View File

@ -3,7 +3,7 @@
from django.http import HttpResponse
from rest_framework.fields import CharField
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.planner import FlowPlan
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_PLAN
@ -38,6 +38,7 @@ class OAuthDeviceCodeFinishStage(ChallengeStageView):
token.save()
return OAuthDeviceCodeFinishChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-provider-oauth2-device-code-finish",
}
)

View File

@ -10,7 +10,7 @@ from structlog.stdlib import get_logger
from authentik.brands.models import Brand
from authentik.core.models import Application
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import in_memory_stage
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner
@ -141,6 +141,7 @@ class OAuthDeviceCodeStage(ChallengeStageView):
def get_challenge(self, *args, **kwargs) -> Challenge:
return OAuthDeviceCodeChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-provider-oauth2-device-code",
}
)

View File

@ -16,6 +16,7 @@ from authentik.flows.challenge import (
AutoSubmitChallengeResponse,
Challenge,
ChallengeResponse,
ChallengeTypes,
)
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION
from authentik.flows.stage import ChallengeStageView
@ -80,6 +81,7 @@ class SAMLFlowFinalView(ChallengeStageView):
return super().get(
self.request,
**{
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-autosubmit",
"title": self.executor.plan.context.get(
PLAN_CONTEXT_TITLE,

View File

@ -5,7 +5,6 @@ from collections import OrderedDict
from hashlib import sha512
from pathlib import Path
import orjson
from celery.schedules import crontab
from django.conf import ImproperlyConfigured
from sentry_sdk import set_tag
@ -148,6 +147,7 @@ SPECTACULAR_SETTINGS = {
},
"ENUM_NAME_OVERRIDES": {
"EventActions": "authentik.events.models.EventAction",
"ChallengeChoices": "authentik.flows.challenge.ChallengeTypes",
"FlowDesignationEnum": "authentik.flows.models.FlowDesignation",
"FlowLayoutEnum": "authentik.flows.models.FlowLayout",
"PolicyEngineMode": "authentik.policies.models.PolicyEngineMode",
@ -178,20 +178,16 @@ REST_FRAMEWORK = {
"rest_framework.filters.OrderingFilter",
"rest_framework.filters.SearchFilter",
],
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
],
"DEFAULT_PERMISSION_CLASSES": ("authentik.rbac.permissions.ObjectPermissions",),
"DEFAULT_AUTHENTICATION_CLASSES": (
"authentik.api.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication",
),
"DEFAULT_RENDERER_CLASSES": [
"drf_orjson_renderer.renderers.ORJSONRenderer",
],
"ORJSON_RENDERER_OPTIONS": [
orjson.OPT_NON_STR_KEYS,
orjson.OPT_UTC_Z,
],
"DEFAULT_PARSER_CLASSES": [
"drf_orjson_renderer.parsers.ORJSONParser",
"rest_framework.renderers.JSONRenderer",
],
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"TEST_REQUEST_DEFAULT_FORMAT": "json",

View File

@ -31,9 +31,9 @@ def set_default_group_mappings(apps: Apps, schema_editor):
db_alias = schema_editor.connection.alias
for source in LDAPSource.objects.using(db_alias).all():
if source.property_mappings_group.using(db_alias).exists():
if source.property_mappings_group.exists():
continue
source.property_mappings_group.using(db_alias).set(
source.property_mappings_group.set(
LDAPPropertyMapping.objects.using(db_alias).filter(
managed="goauthentik.io/sources/ldap/default-name"
)

View File

@ -9,7 +9,7 @@ from jwt import decode, encode
from rest_framework.fields import CharField
from structlog.stdlib import get_logger
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.sources.oauth.clients.oauth2 import OAuth2Client
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.types.registry import SourceType, registry
@ -130,5 +130,6 @@ class AppleType(SourceType):
"scope": "name email",
"redirect_uri": args["redirect_uri"],
"state": args["state"],
"type": ChallengeTypes.NATIVE.value,
}
)

View File

@ -8,7 +8,7 @@ from django.templatetags.static import static
from django.urls.base import reverse
from structlog.stdlib import get_logger
from authentik.flows.challenge import Challenge, RedirectChallenge
from authentik.flows.challenge import Challenge, ChallengeTypes, RedirectChallenge
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.views.callback import OAuthCallback
from authentik.sources.oauth.views.redirect import OAuthRedirect
@ -48,6 +48,7 @@ class SourceType:
"""Allow types to return custom challenges"""
return RedirectChallenge(
data={
"type": ChallengeTypes.REDIRECT.value,
"to": reverse(
"authentik_sources_oauth:oauth-client-login",
kwargs={"source_slug": source.slug},

View File

@ -10,7 +10,7 @@ from rest_framework.serializers import BaseSerializer, Serializer
from authentik.core.models import Source, UserSourceConnection
from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.lib.generators import generate_id
@ -71,6 +71,7 @@ class PlexSource(Source):
return UILoginButton(
challenge=PlexAuthenticationChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-source-plex",
"client_id": self.client_id,
"slug": self.slug,

View File

@ -10,8 +10,6 @@ from authentik.sources.saml.processors import constants
def update_algorithms(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
SAMLSource = apps.get_model("authentik_sources_saml", "SAMLSource")
signature_translation_map = {
"rsa-sha1": constants.RSA_SHA1,
@ -24,7 +22,7 @@ def update_algorithms(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
"sha256": constants.SHA256,
}
for source in SAMLSource.objects.using(db_alias).all():
for source in SAMLSource.objects.all():
source.signature_algorithm = signature_translation_map.get(
source.signature_algorithm, constants.RSA_SHA256
)

View File

@ -10,7 +10,7 @@ from rest_framework.serializers import Serializer
from authentik.core.models import Source, UserSourceConnection
from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.crypto.models import CertificateKeyPair
from authentik.flows.challenge import RedirectChallenge
from authentik.flows.challenge import ChallengeTypes, RedirectChallenge
from authentik.flows.models import Flow
from authentik.lib.utils.time import timedelta_string_validator
from authentik.sources.saml.processors.constants import (
@ -204,6 +204,7 @@ class SAMLSource(Source):
return UILoginButton(
challenge=RedirectChallenge(
data={
"type": ChallengeTypes.REDIRECT.value,
"to": reverse(
"authentik_sources_saml:login",
kwargs={"source_slug": self.slug},

View File

@ -21,6 +21,7 @@ from authentik.flows.challenge import (
AutosubmitChallenge,
Challenge,
ChallengeResponse,
ChallengeTypes,
)
from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import in_memory_stage
@ -51,6 +52,7 @@ class AutosubmitStageView(ChallengeStageView):
def get_challenge(self, *args, **kwargs) -> Challenge:
return AutosubmitChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-autosubmit",
"title": self.executor.plan.context.get(PLAN_CONTEXT_TITLE, ""),
"url": self.executor.plan.context.get(PLAN_CONTEXT_URL, ""),

View File

@ -8,6 +8,7 @@ from authentik.events.models import Event, EventAction
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.stage import ChallengeStageView
@ -60,6 +61,7 @@ class AuthenticatorDuoStageView(ChallengeStageView):
enroll = self.request.session[SESSION_KEY_DUO_ENROLL]
return AuthenticatorDuoChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"activation_barcode": enroll["activation_barcode"],
"activation_code": enroll["activation_code"],
"stage_uuid": str(stage.stage_uuid),

View File

@ -10,6 +10,7 @@ from rest_framework.fields import BooleanField, CharField, IntegerField
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.stage import ChallengeStageView
@ -89,6 +90,7 @@ class AuthenticatorSMSStageView(ChallengeStageView):
def get_challenge(self, *args, **kwargs) -> Challenge:
return AuthenticatorSMSChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"phone_number_required": self._has_phone_number() is None,
}
)

View File

@ -3,7 +3,7 @@
from django.http import HttpRequest, HttpResponse
from rest_framework.fields import CharField, ListField
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
from authentik.flows.stage import ChallengeStageView
from authentik.lib.generators import generate_id
from authentik.stages.authenticator_static.models import (
@ -38,6 +38,7 @@ class AuthenticatorStaticStageView(ChallengeStageView):
tokens: list[StaticToken] = self.request.session[SESSION_STATIC_TOKENS]
return AuthenticatorStaticChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"codes": [token.token for token in tokens],
}
)

View File

@ -11,6 +11,7 @@ from rest_framework.serializers import ValidationError
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.stage import ChallengeStageView
@ -54,6 +55,7 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
device: TOTPDevice = self.request.session[SESSION_TOTP_DEVICE]
return AuthenticatorTOTPChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"config_url": device.config_url.replace(
OTP_TOTP_ISSUER, quote(self.request.brand.branding_title)
),

View File

@ -13,7 +13,7 @@ def migrate_configuration_stage(apps: Apps, schema_editor: BaseDatabaseSchemaEdi
for stage in AuthenticatorValidateStage.objects.using(db_alias).all():
if stage.configuration_stage:
stage.configuration_stages.using(db_alias).set([stage.configuration_stage])
stage.configuration_stages.set([stage.configuration_stage])
stage.save()

View File

@ -13,7 +13,7 @@ from rest_framework.serializers import ValidationError
from authentik.core.api.utils import JSONDictField, PassiveSerializer
from authentik.core.models import User
from authentik.events.models import Event, EventAction
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
from authentik.flows.exceptions import FlowSkipStageException, StageInvalidException
from authentik.flows.models import FlowDesignation, NotConfiguredAction, Stage
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
@ -325,7 +325,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
serializer = SelectableStageSerializer(
data={
"pk": stage.pk,
"name": getattr(stage, "friendly_name", stage.name),
"name": stage.friendly_name or stage.name,
"verbose_name": str(stage._meta.verbose_name)
.replace("Setup Stage", "")
.strip(),
@ -337,6 +337,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
return AuthenticatorValidationChallenge(
data={
"component": "ak-stage-authenticator-validate",
"type": ChallengeTypes.NATIVE.value,
"device_challenges": challenges,
"configuration_stages": stage_challenges,
}

View File

@ -30,6 +30,7 @@ from authentik.core.models import User
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.stage import ChallengeStageView
@ -143,6 +144,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
self.request.session.save()
return AuthenticatorWebAuthnChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"registration": loads(options_to_json(registration_options)),
}
)

View File

@ -9,6 +9,7 @@ from rest_framework.serializers import ValidationError
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.stage import ChallengeStageView
@ -79,6 +80,7 @@ class CaptchaStageView(ChallengeStageView):
return CaptchaChallenge(
data={
"js_url": self.executor.current_stage.js_url,
"type": ChallengeTypes.NATIVE.value,
"site_key": self.executor.current_stage.public_key,
}
)

View File

@ -10,6 +10,7 @@ from authentik.core.api.utils import PassiveSerializer
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_PENDING_USER
@ -57,6 +58,7 @@ class ConsentStageView(ChallengeStageView):
token = str(uuid4())
self.request.session[SESSION_KEY_CONSENT_TOKEN] = token
data = {
"type": ChallengeTypes.NATIVE.value,
"permissions": self.executor.plan.context.get(PLAN_CONTEXT_CONSENT_PERMISSIONS, []),
"additional_permissions": self.executor.plan.context.get(
PLAN_CONTEXT_CONSENT_EXTRA_PERMISSIONS, []

View File

@ -3,7 +3,7 @@
from django.http.response import HttpResponse
from rest_framework.fields import CharField
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.stage import ChallengeStageView
from authentik.lib.sentry import SentryIgnoredException
@ -34,6 +34,7 @@ class DummyStageView(ChallengeStageView):
raise SentryIgnoredException("Test error")
return DummyChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"title": self.executor.current_stage.name,
"name": self.executor.current_stage.name,
}

View File

@ -15,7 +15,7 @@ from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError
from authentik.events.models import Event, EventAction
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.exceptions import StageInvalidException
from authentik.flows.models import FlowDesignation, FlowToken
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED, PLAN_CONTEXT_PENDING_USER
@ -160,6 +160,7 @@ class EmailStageView(ChallengeStageView):
def get_challenge(self) -> Challenge:
challenge = EmailChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"title": _("Email sent."),
}
)

View File

@ -13,9 +13,9 @@ def assign_sources(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
IdentificationStage = apps.get_model("authentik_stages_identification", "identificationstage")
Source = apps.get_model("authentik_core", "source")
sources = Source.objects.using(db_alias).all()
for stage in IdentificationStage.objects.using(db_alias).all():
stage.sources.using(db_alias).set(sources)
sources = Source.objects.all()
for stage in IdentificationStage.objects.all().using(db_alias):
stage.sources.set(sources)
stage.save()

View File

@ -38,11 +38,10 @@ class IdentificationStage(Stage):
help_text=_(
(
"When set, shows a password field, instead of showing the "
"password field as separate step."
"password field as seaprate step."
),
),
)
case_insensitive_matching = models.BooleanField(
default=True,
help_text=_("When enabled, user fields are matched regardless of their casing."),

View File

@ -20,6 +20,7 @@ from authentik.events.utils import sanitize_item
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
RedirectChallenge,
)
from authentik.flows.models import FlowDesignation
@ -64,7 +65,6 @@ class IdentificationChallenge(Challenge):
user_fields = ListField(child=CharField(), allow_empty=True, allow_null=True)
password_fields = BooleanField()
allow_show_password = BooleanField(default=False)
application_pre = CharField(required=False)
flow_designation = ChoiceField(FlowDesignation.choices)
@ -194,12 +194,11 @@ class IdentificationStageView(ChallengeStageView):
current_stage: IdentificationStage = self.executor.current_stage
challenge = IdentificationChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-identification",
"primary_action": self.get_primary_action(),
"user_fields": current_stage.user_fields,
"password_fields": bool(current_stage.password_stage),
"allow_show_password": bool(current_stage.password_stage)
and current_stage.password_stage.allow_show_password,
"show_source_labels": current_stage.show_source_labels,
"flow_designation": self.executor.flow.designation,
}

View File

@ -4,6 +4,7 @@ from django.urls import reverse
from rest_framework.exceptions import ValidationError
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.challenge import ChallengeTypes
from authentik.flows.models import FlowDesignation, FlowStageBinding
from authentik.flows.tests import FlowTestCase
from authentik.lib.generators import generate_id
@ -89,6 +90,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
"icon_url": "/static/authentik/sources/default.svg",
"name": "test",
@ -124,6 +126,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
"icon_url": "/static/authentik/sources/default.svg",
"name": "test",
@ -186,6 +189,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
"icon_url": "/static/authentik/sources/default.svg",
"name": "test",
@ -236,6 +240,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
}
],
@ -271,6 +276,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
"icon_url": "/static/authentik/sources/default.svg",
"name": "test",
@ -298,6 +304,7 @@ class TestIdentificationStage(FlowTestCase):
"challenge": {
"component": "xak-flow-redirect",
"to": "/source/oauth/login/test/",
"type": ChallengeTypes.REDIRECT.value,
},
"icon_url": "/static/authentik/sources/default.svg",
"name": "test",

View File

@ -16,7 +16,6 @@ class PasswordStageSerializer(StageSerializer):
"backends",
"configure_flow",
"failed_attempts_before_cancel",
"allow_show_password",
]
@ -29,7 +28,6 @@ class PasswordStageViewSet(UsedByMixin, ModelViewSet):
"name",
"configure_flow",
"failed_attempts_before_cancel",
"allow_show_password",
]
search_fields = ["name"]
ordering = ["name"]

View File

@ -1,21 +0,0 @@
# Generated by Django 5.0.6 on 2024-07-02 18:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_password", "0008_replace_inbuilt"),
]
operations = [
migrations.AddField(
model_name="passwordstage",
name="allow_show_password",
field=models.BooleanField(
default=False,
help_text="When enabled, provides a 'show password' button with the password input field.",
),
),
]

View File

@ -43,12 +43,6 @@ class PasswordStage(ConfigurableStage, Stage):
"To lock the user out, use a reputation policy and a user_write stage."
),
)
allow_show_password = models.BooleanField(
default=False,
help_text=_(
"When enabled, provides a 'show password' button with the password input field."
),
)
@property
def serializer(self) -> type[BaseSerializer]:

View File

@ -9,7 +9,7 @@ from django.http import HttpRequest, HttpResponse
from django.urls import reverse
from django.utils.translation import gettext as _
from rest_framework.exceptions import ValidationError
from rest_framework.fields import BooleanField, CharField
from rest_framework.fields import CharField
from sentry_sdk.hub import Hub
from structlog.stdlib import get_logger
@ -18,6 +18,7 @@ from authentik.core.signals import login_failed
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.exceptions import StageInvalidException
@ -76,8 +77,6 @@ class PasswordChallenge(WithUserInfoChallenge):
component = CharField(default="ak-stage-password")
allow_show_password = BooleanField(default=False)
class PasswordChallengeResponse(ChallengeResponse):
"""Password challenge response"""
@ -138,7 +137,7 @@ class PasswordStageView(ChallengeStageView):
def get_challenge(self) -> Challenge:
challenge = PasswordChallenge(
data={
"allow_show_password": self.executor.current_stage.allow_show_password,
"type": ChallengeTypes.NATIVE.value,
}
)
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY)

View File

@ -11,7 +11,7 @@ from rest_framework.viewsets import ModelViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.flows.api.stages import StageSerializer
from authentik.flows.challenge import HttpChallengeResponse
from authentik.flows.challenge import ChallengeTypes, HttpChallengeResponse
from authentik.flows.planner import FlowPlan
from authentik.flows.views.executor import FlowExecutorView
from authentik.lib.generators import generate_id
@ -115,6 +115,7 @@ class PromptViewSet(UsedByMixin, ModelViewSet):
)
challenge = PromptChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"fields": fields,
},
)

View File

@ -12,7 +12,7 @@ def set_generated_name(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
for prompt in Prompt.objects.using(db_alias).all():
name = prompt.field_key
stage = prompt.promptstage_set.using(db_alias).order_by("name").first()
stage = prompt.promptstage_set.order_by("name").first()
if stage:
name += "_" + stage.name
else:

View File

@ -21,7 +21,7 @@ from rest_framework.serializers import ValidationError
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import User
from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.planner import FlowPlan
from authentik.flows.stage import ChallengeStageView
from authentik.policies.engine import PolicyEngine
@ -227,6 +227,7 @@ class PromptStageView(ChallengeStageView):
serializers = self.get_prompt_challenge_fields(fields, context_prompt)
challenge = PromptChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"fields": serializers,
},
)

View File

@ -7,6 +7,7 @@ from django.urls import reverse
from rest_framework.exceptions import ErrorDetail, ValidationError
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.challenge import ChallengeTypes
from authentik.flows.markers import StageMarker
from authentik.flows.models import FlowStageBinding
from authentik.flows.planner import FlowPlan
@ -595,6 +596,7 @@ class TestPromptStage(FlowTestCase):
self.assertJSONEqual(
response.content.decode(),
{
"type": ChallengeTypes.NATIVE.value,
"component": "ak-stage-prompt",
"fields": [
{

View File

@ -10,7 +10,7 @@ from rest_framework.fields import BooleanField, CharField
from authentik.core.models import AuthenticatedSession, User
from authentik.events.middleware import audit_ignore
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE
from authentik.flows.stage import ChallengeStageView
from authentik.lib.utils.time import timedelta_from_string
@ -45,7 +45,11 @@ class UserLoginStageView(ChallengeStageView):
response_class = UserLoginChallengeResponse
def get_challenge(self, *args, **kwargs) -> UserLoginChallenge:
return UserLoginChallenge(data={})
return UserLoginChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
}
)
def dispatch(self, request: HttpRequest) -> HttpResponse:
"""Check for remember_me, and do login"""

View File

@ -129,11 +129,6 @@ class TestUserLoginStage(FlowTestCase):
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
)
self.assertStageResponse(response, component="ak-stage-user-login")
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
data={"remember_me": True},

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2024.6.1 Blueprint schema",
"title": "authentik 2024.6.0 Blueprint schema",
"required": [
"version",
"entries"
@ -6905,7 +6905,7 @@
"password_stage": {
"type": "integer",
"title": "Password stage",
"description": "When set, shows a password field, instead of showing the password field as separate step."
"description": "When set, shows a password field, instead of showing the password field as seaprate step."
},
"case_insensitive_matching": {
"type": "boolean",
@ -7207,11 +7207,6 @@
"maximum": 2147483647,
"title": "Failed attempts before cancel",
"description": "How many attempts a user has before the flow is canceled. To lock the user out, use a reputation policy and a user_write stage."
},
"allow_show_password": {
"type": "boolean",
"title": "Allow show password",
"description": "When enabled, provides a 'show password' button with the password input field."
}
},
"required": []

View File

@ -31,7 +31,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.1}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.0}
restart: unless-stopped
command: server
environment:
@ -52,7 +52,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.1}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.0}
restart: unless-stopped
command: worker
environment:

18
go.mod
View File

@ -4,7 +4,7 @@ go 1.22.2
require (
beryju.io/ldap v0.1.0
github.com/coreos/go-oidc/v3 v3.11.0
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/getsentry/sentry-go v0.28.1
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
github.com/go-ldap/ldap/v3 v3.4.8
@ -22,13 +22,13 @@ require (
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/pires/go-proxyproto v0.7.0
github.com/prometheus/client_golang v1.19.1
github.com/redis/go-redis/v9 v9.5.4
github.com/sethvargo/go-envconfig v1.1.0
github.com/redis/go-redis/v9 v9.5.3
github.com/sethvargo/go-envconfig v1.0.3
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2024061.3
goauthentik.io/api/v3 v3.2024060.2
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.21.0
golang.org/x/sync v0.7.0
@ -47,7 +47,6 @@ require (
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 // indirect
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
@ -64,6 +63,7 @@ require (
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
@ -72,9 +72,11 @@ require (
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

36
go.sum
View File

@ -55,8 +55,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -84,8 +84,6 @@ github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 h1:O6yi4xa9b2D
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27/go.mod h1:AYvN8omj7nKLmbcXS2dyABYU6JB1Lz1bHmkkq1kf4I4=
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno=
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -233,6 +231,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac h1:jWKYCNlX4J5s8M0nHYkh7Y7c9gRVDEb3mq51j5J0F5M=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -242,14 +242,14 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/redis/go-redis/v9 v9.5.4 h1:vOFYDKKVgrI5u++QvnMT7DksSMYg7Aw/Np4vLJLKLwY=
github.com/redis/go-redis/v9 v9.5.4/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU=
github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sethvargo/go-envconfig v1.1.0 h1:cWZiJxeTm7AlCvzGXrEXaSTCNgip5oJepekh/BOQuog=
github.com/sethvargo/go-envconfig v1.1.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
github.com/sethvargo/go-envconfig v1.0.3 h1:ZDxFGT1M7RPX0wgDOCdZMidrEB+NrayYr6fL0/+pk4I=
github.com/sethvargo/go-envconfig v1.0.3/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@ -264,6 +264,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -293,8 +294,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
goauthentik.io/api/v3 v3.2024061.3 h1:gbP8mhHE2/iCDSZEnAUvRkh9DQhggdTfhsEYKg3sp/U=
goauthentik.io/api/v3 v3.2024061.3/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2024060.2 h1:rnZlHFzuHJQ5sU1V7XVZhWRtlSuvrf2QLzBSNtLexi8=
goauthentik.io/api/v3 v3.2024060.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -304,9 +305,8 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -374,8 +374,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -430,9 +430,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -447,9 +446,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -579,6 +577,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

View File

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

View File

@ -183,7 +183,7 @@ func (ac *APIController) startWSHealth() {
func (ac *APIController) startIntervalUpdater() {
logger := ac.logger.WithField("loop", "interval-updater")
ticker := time.NewTicker(time.Duration(ac.Outpost.RefreshIntervalS) * time.Second)
ticker := time.NewTicker(5 * time.Minute)
for ; true; <-ticker.C {
logger.Debug("Running interval update")
err := ac.OnRefresh()
@ -198,7 +198,6 @@ func (ac *APIController) startIntervalUpdater() {
"build": constants.BUILD("tagged"),
}).SetToCurrentTime()
}
ticker.Reset(time.Duration(ac.Outpost.RefreshIntervalS) * time.Second)
}
}

View File

@ -8,7 +8,6 @@ const (
StageIdentification = StageComponent("ak-stage-identification")
StagePassword = StageComponent("ak-stage-password")
StageUserLogin = StageComponent("ak-stage-user-login")
StageRedirect = StageComponent("xak-flow-redirect")
)
const (

View File

@ -110,8 +110,9 @@ func (fe *FlowExecutor) ApiClient() *api.APIClient {
return fe.api
}
type challengeCommon interface {
type challengeInt interface {
GetComponent() string
GetType() api.ChallengeChoices
GetResponseErrors() map[string][]api.ErrorDetail
}
@ -180,8 +181,9 @@ func (fe *FlowExecutor) getInitialChallenge() (*api.ChallengeTypes, error) {
if i == nil {
return nil, errors.New("response instance was null")
}
ch := i.(challengeCommon)
fe.log.WithField("component", ch.GetComponent()).Debug("Got challenge")
ch := i.(challengeInt)
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge")
gcsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
gcsp.SetTag("authentik.flow.component", ch.GetComponent())
gcsp.Finish()
FlowTimingGet.With(prometheus.Labels{
@ -199,7 +201,7 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
if i == nil {
return false, errors.New("response request instance was null")
}
ch := i.(challengeCommon)
ch := i.(challengeInt)
// Check for any validation errors that we might've gotten
if len(ch.GetResponseErrors()) > 0 {
@ -210,12 +212,13 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
}
}
switch ch.GetComponent() {
case string(StageAccessDenied):
return false, nil
case string(StageRedirect):
switch ch.GetType() {
case api.CHALLENGECHOICES_REDIRECT:
return true, nil
default:
case api.CHALLENGECHOICES_NATIVE:
if ch.GetComponent() == string(StageAccessDenied) {
return false, nil
}
solver, ok := fe.solvers[StageComponent(ch.GetComponent())]
if !ok {
return false, fmt.Errorf("unsupported challenge type %s", ch.GetComponent())
@ -235,8 +238,9 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
if i == nil {
return false, errors.New("response instance was null")
}
ch = i.(challengeCommon)
fe.log.WithField("component", ch.GetComponent()).Debug("Got response")
ch = i.(challengeInt)
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response")
scsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
scsp.SetTag("authentik.flow.component", ch.GetComponent())
scsp.Finish()
FlowTimingPost.With(prometheus.Labels{

View File

@ -1,13 +0,0 @@
package flow
import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api/v3"
)
func TestConvert(t *testing.T) {
var a challengeCommon = api.NewIdentificationChallengeWithDefaults()
assert.NotNil(t, a)
}

View File

@ -14,7 +14,7 @@ import (
"strings"
"time"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/coreos/go-oidc"
"github.com/getsentry/sentry-go"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/gorilla/mux"

View File

@ -48,9 +48,9 @@
<footer class="pf-c-login__footer">
<ul class="pf-c-list pf-m-inline">
<li>
<span>
<a rel="noopener noreferrer" target="_blank" href="https://goauthentik.io?utm_source=authentik_outpost&utm_campaign=proxy_error">
Powered by authentik
</span>
</a>
</li>
</ul>
</footer>

View File

@ -1,5 +1,5 @@
{
"name": "@goauthentik/authentik",
"version": "2024.6.1",
"version": "2024.6.0",
"private": true
}

471
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "aiohttp"
@ -639,13 +639,13 @@ zstd = ["zstandard (==0.22.0)"]
[[package]]
name = "certifi"
version = "2024.7.4"
version = "2024.2.2"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
{file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
]
[[package]]
@ -956,63 +956,63 @@ files = [
[[package]]
name = "coverage"
version = "7.6.0"
version = "7.5.4"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"},
{file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"},
{file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"},
{file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"},
{file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"},
{file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"},
{file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"},
{file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"},
{file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"},
{file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"},
{file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"},
{file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"},
{file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"},
{file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"},
{file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"},
{file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"},
{file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"},
{file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"},
{file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"},
{file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"},
{file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"},
{file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"},
{file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"},
{file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"},
{file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"},
{file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"},
{file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"},
{file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"},
{file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"},
{file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"},
{file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"},
{file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"},
{file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"},
{file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"},
{file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"},
{file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"},
{file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"},
{file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"},
{file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"},
{file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"},
{file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"},
{file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"},
{file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"},
{file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"},
{file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"},
{file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"},
{file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"},
{file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"},
{file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"},
{file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"},
{file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"},
{file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"},
{file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"},
{file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"},
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"},
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"},
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"},
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"},
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"},
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"},
{file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"},
{file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"},
{file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"},
{file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"},
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"},
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"},
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"},
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"},
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"},
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"},
{file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"},
{file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"},
{file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"},
{file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"},
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"},
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"},
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"},
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"},
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"},
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"},
{file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"},
{file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"},
{file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"},
{file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"},
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"},
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"},
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"},
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"},
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"},
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"},
{file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"},
{file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"},
{file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"},
{file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"},
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"},
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"},
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"},
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"},
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"},
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"},
{file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"},
{file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"},
{file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"},
{file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"},
]
[package.extras]
@ -1176,13 +1176,13 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"]
[[package]]
name = "django"
version = "5.0.7"
version = "5.0.6"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.10"
files = [
{file = "Django-5.0.7-py3-none-any.whl", hash = "sha256:f216510ace3de5de01329463a315a629f33480e893a9024fc93d8c32c22913da"},
{file = "Django-5.0.7.tar.gz", hash = "sha256:bd4505cae0b9bd642313e8fb71810893df5dc2ffcacaa67a33af2d5cd61888f2"},
{file = "Django-5.0.6-py3-none-any.whl", hash = "sha256:8363ac062bb4ef7c3f12d078f6fa5d154031d129a15170a1066412af49d30905"},
{file = "Django-5.0.6.tar.gz", hash = "sha256:ff1b61005004e476e0aeea47c7f79b85864c70124030e95146315396f1e7951f"},
]
[package.dependencies]
@ -1310,13 +1310,13 @@ hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"]
[[package]]
name = "django-storages"
version = "1.14.4"
version = "1.14.3"
description = "Support for many storage backends in Django"
optional = false
python-versions = ">=3.7"
files = [
{file = "django-storages-1.14.4.tar.gz", hash = "sha256:69aca94d26e6714d14ad63f33d13619e697508ee33ede184e462ed766dc2a73f"},
{file = "django_storages-1.14.4-py3-none-any.whl", hash = "sha256:d61930acb4a25e3aebebc6addaf946a3b1df31c803a6bf1af2f31c9047febaa3"},
{file = "django-storages-1.14.3.tar.gz", hash = "sha256:95a12836cd998d4c7a4512347322331c662d9114c4344f932f5e9c0fce000608"},
{file = "django_storages-1.14.3-py3-none-any.whl", hash = "sha256:31f263389e95ce3a1b902fb5f739a7ed32895f7d8b80179fe7453ecc0dfe102e"},
]
[package.dependencies]
@ -1446,22 +1446,6 @@ docs = ["sphinx", "sphinx-rtd-theme"]
release = ["bump-my-version", "twine"]
tests = ["black", "django-stubs[compatible-mypy]", "djangorestframework-stubs[compatible-mypy]", "flake8", "fqdn", "idna", "isoduration", "isort", "jsonpointer", "mypy", "pytest", "pytest-django", "rfc3339-validator", "rfc3987", "tox", "types-jsonschema", "uri-template", "webcolors"]
[[package]]
name = "drf-orjson-renderer"
version = "1.7.2"
description = "Django RestFramework JSON Renderer Backed by orjson"
optional = false
python-versions = ">=3.6.0"
files = [
{file = "drf_orjson_renderer-1.7.2-py3-none-any.whl", hash = "sha256:4fbf6f91d7032fbf23e31837e4c5cf6950af4e588bf34e9feadc809c67977657"},
{file = "drf_orjson_renderer-1.7.2.tar.gz", hash = "sha256:b8a47c38a6eeaf5ffc7a5d53d028b95fa8b340999507681e403a599f0a3be456"},
]
[package.dependencies]
django = ">=3.2"
djangorestframework = "*"
orjson = ">=3.3.0"
[[package]]
name = "drf-spectacular"
version = "0.27.2"
@ -1723,13 +1707,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
version = "2.137.0"
version = "2.136.0"
description = "Google API Client Library for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "google_api_python_client-2.137.0-py2.py3-none-any.whl", hash = "sha256:a8b5c5724885e5be9f5368739aa0ccf416627da4ebd914b410a090c18f84d692"},
{file = "google_api_python_client-2.137.0.tar.gz", hash = "sha256:e739cb74aac8258b1886cb853b0722d47c81fe07ad649d7f2206f06530513c04"},
{file = "google-api-python-client-2.136.0.tar.gz", hash = "sha256:161c722c8864e7ed39393e2b7eea76ef4e1c933a6a59f9d7c70409b6635f225d"},
{file = "google_api_python_client-2.136.0-py2.py3-none-any.whl", hash = "sha256:5a554c8b5edf0a609b905d89d7ced82e8f6ac31da1e4d8d5684ef63dbc0e49f5"},
]
[package.dependencies]
@ -2816,13 +2800,13 @@ dev = ["bumpver", "isort", "mypy", "pylint", "pytest", "yapf"]
[[package]]
name = "msgraph-sdk"
version = "1.5.2"
version = "1.4.0"
description = "The Microsoft Graph Python SDK"
optional = false
python-versions = ">=3.8"
files = [
{file = "msgraph_sdk-1.5.2-py3-none-any.whl", hash = "sha256:e3ee67dbbb5b2233aae291996cb846c0d32017f085a23476ab98198aa513a0dd"},
{file = "msgraph_sdk-1.5.2.tar.gz", hash = "sha256:62f2b1e7f8e9438a5a30b1e1761b8c4cbc4dc026a54088c381861aab6f266f92"},
{file = "msgraph_sdk-1.4.0-py3-none-any.whl", hash = "sha256:24f99082475ea129c3d45e44269bd64a7c6bfef8dda4f8ea692bbc9e47b71b78"},
{file = "msgraph_sdk-1.4.0.tar.gz", hash = "sha256:715907272c240e579d7669a690504488e25ae15fec904e2918c49ca328dc4a14"},
]
[package.dependencies]
@ -2834,7 +2818,7 @@ microsoft-kiota-serialization-form = ">=0.1.0"
microsoft-kiota-serialization-json = ">=1.0.0,<2.0.0"
microsoft-kiota-serialization-multipart = ">=0.1.0"
microsoft-kiota-serialization-text = ">=1.0.0,<2.0.0"
msgraph_core = ">=1.0.0"
msgraph-core = ">=1.0.0"
[package.extras]
dev = ["bumpver", "isort", "mypy", "pylint", "pytest", "yapf"]
@ -3034,61 +3018,6 @@ files = [
[package.dependencies]
opentelemetry-api = "1.25.0"
[[package]]
name = "orjson"
version = "3.10.3"
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
optional = false
python-versions = ">=3.8"
files = [
{file = "orjson-3.10.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9fb6c3f9f5490a3eb4ddd46fc1b6eadb0d6fc16fb3f07320149c3286a1409dd8"},
{file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:252124b198662eee80428f1af8c63f7ff077c88723fe206a25df8dc57a57b1fa"},
{file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f3e87733823089a338ef9bbf363ef4de45e5c599a9bf50a7a9b82e86d0228da"},
{file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8334c0d87103bb9fbbe59b78129f1f40d1d1e8355bbed2ca71853af15fa4ed3"},
{file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1952c03439e4dce23482ac846e7961f9d4ec62086eb98ae76d97bd41d72644d7"},
{file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0403ed9c706dcd2809f1600ed18f4aae50be263bd7112e54b50e2c2bc3ebd6d"},
{file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:382e52aa4270a037d41f325e7d1dfa395b7de0c367800b6f337d8157367bf3a7"},
{file = "orjson-3.10.3-cp310-none-win32.whl", hash = "sha256:be2aab54313752c04f2cbaab4515291ef5af8c2256ce22abc007f89f42f49109"},
{file = "orjson-3.10.3-cp310-none-win_amd64.whl", hash = "sha256:416b195f78ae461601893f482287cee1e3059ec49b4f99479aedf22a20b1098b"},
{file = "orjson-3.10.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:73100d9abbbe730331f2242c1fc0bcb46a3ea3b4ae3348847e5a141265479700"},
{file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a12eee96e3ab828dbfcb4d5a0023aa971b27143a1d35dc214c176fdfb29b3"},
{file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520de5e2ef0b4ae546bea25129d6c7c74edb43fc6cf5213f511a927f2b28148b"},
{file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccaa0a401fc02e8828a5bedfd80f8cd389d24f65e5ca3954d72c6582495b4bcf"},
{file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7bc9e8bc11bac40f905640acd41cbeaa87209e7e1f57ade386da658092dc16"},
{file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3582b34b70543a1ed6944aca75e219e1192661a63da4d039d088a09c67543b08"},
{file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c23dfa91481de880890d17aa7b91d586a4746a4c2aa9a145bebdbaf233768d5"},
{file = "orjson-3.10.3-cp311-none-win32.whl", hash = "sha256:1770e2a0eae728b050705206d84eda8b074b65ee835e7f85c919f5705b006c9b"},
{file = "orjson-3.10.3-cp311-none-win_amd64.whl", hash = "sha256:93433b3c1f852660eb5abdc1f4dd0ced2be031ba30900433223b28ee0140cde5"},
{file = "orjson-3.10.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a39aa73e53bec8d410875683bfa3a8edf61e5a1c7bb4014f65f81d36467ea098"},
{file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0943a96b3fa09bee1afdfccc2cb236c9c64715afa375b2af296c73d91c23eab2"},
{file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e852baafceff8da3c9defae29414cc8513a1586ad93e45f27b89a639c68e8176"},
{file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18566beb5acd76f3769c1d1a7ec06cdb81edc4d55d2765fb677e3eaa10fa99e0"},
{file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd2218d5a3aa43060efe649ec564ebedec8ce6ae0a43654b81376216d5ebd42"},
{file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cf20465e74c6e17a104ecf01bf8cd3b7b252565b4ccee4548f18b012ff2f8069"},
{file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba7f67aa7f983c4345eeda16054a4677289011a478ca947cd69c0a86ea45e534"},
{file = "orjson-3.10.3-cp312-none-win32.whl", hash = "sha256:17e0713fc159abc261eea0f4feda611d32eabc35708b74bef6ad44f6c78d5ea0"},
{file = "orjson-3.10.3-cp312-none-win_amd64.whl", hash = "sha256:4c895383b1ec42b017dd2c75ae8a5b862fc489006afde06f14afbdd0309b2af0"},
{file = "orjson-3.10.3-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:be2719e5041e9fb76c8c2c06b9600fe8e8584e6980061ff88dcbc2691a16d20d"},
{file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0175a5798bdc878956099f5c54b9837cb62cfbf5d0b86ba6d77e43861bcec2"},
{file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978be58a68ade24f1af7758626806e13cff7748a677faf95fbb298359aa1e20d"},
{file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16bda83b5c61586f6f788333d3cf3ed19015e3b9019188c56983b5a299210eb5"},
{file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ad1f26bea425041e0a1adad34630c4825a9e3adec49079b1fb6ac8d36f8b754"},
{file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9e253498bee561fe85d6325ba55ff2ff08fb5e7184cd6a4d7754133bd19c9195"},
{file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0a62f9968bab8a676a164263e485f30a0b748255ee2f4ae49a0224be95f4532b"},
{file = "orjson-3.10.3-cp38-none-win32.whl", hash = "sha256:8d0b84403d287d4bfa9bf7d1dc298d5c1c5d9f444f3737929a66f2fe4fb8f134"},
{file = "orjson-3.10.3-cp38-none-win_amd64.whl", hash = "sha256:8bc7a4df90da5d535e18157220d7915780d07198b54f4de0110eca6b6c11e290"},
{file = "orjson-3.10.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9059d15c30e675a58fdcd6f95465c1522b8426e092de9fff20edebfdc15e1cb0"},
{file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d40c7f7938c9c2b934b297412c067936d0b54e4b8ab916fd1a9eb8f54c02294"},
{file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a654ec1de8fdaae1d80d55cee65893cb06494e124681ab335218be6a0691e7"},
{file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:831c6ef73f9aa53c5f40ae8f949ff7681b38eaddb6904aab89dca4d85099cb78"},
{file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99b880d7e34542db89f48d14ddecbd26f06838b12427d5a25d71baceb5ba119d"},
{file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e5e176c994ce4bd434d7aafb9ecc893c15f347d3d2bbd8e7ce0b63071c52e25"},
{file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b69a58a37dab856491bf2d3bbf259775fdce262b727f96aafbda359cb1d114d8"},
{file = "orjson-3.10.3-cp39-none-win32.whl", hash = "sha256:b8d4d1a6868cde356f1402c8faeb50d62cee765a1f7ffcfd6de732ab0581e063"},
{file = "orjson-3.10.3-cp39-none-win_amd64.whl", hash = "sha256:5102f50c5fc46d94f2033fe00d392588564378260d64377aec702f21a7a22912"},
{file = "orjson-3.10.3.tar.gz", hash = "sha256:2b166507acae7ba2f7c315dcf185a9111ad5e992ac81f2d507aac39193c2c818"},
]
[[package]]
name = "outcome"
version = "1.3.0.post0"
@ -3462,19 +3391,19 @@ files = [
[[package]]
name = "pydantic"
version = "2.8.2"
version = "2.8.0"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.8"
files = [
{file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"},
{file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"},
{file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"},
{file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"},
]
[package.dependencies]
annotated-types = ">=0.4.0"
email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
pydantic-core = "2.20.1"
pydantic-core = "2.20.0"
typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""}
[package.extras]
@ -3482,100 +3411,99 @@ email = ["email-validator (>=2.0.0)"]
[[package]]
name = "pydantic-core"
version = "2.20.1"
version = "2.20.0"
description = "Core functionality for Pydantic validation and serialization"
optional = false
python-versions = ">=3.8"
files = [
{file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"},
{file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"},
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"},
{file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"},
{file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"},
{file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"},
{file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"},
{file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"},
{file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"},
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"},
{file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"},
{file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"},
{file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"},
{file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"},
{file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"},
{file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"},
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"},
{file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"},
{file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"},
{file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"},
{file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"},
{file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"},
{file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"},
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"},
{file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"},
{file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"},
{file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"},
{file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"},
{file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"},
{file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"},
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"},
{file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"},
{file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"},
{file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"},
{file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"},
{file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"},
{file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"},
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"},
{file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"},
{file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"},
{file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"},
{file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"},
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"},
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"},
{file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"},
{file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"},
{file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"},
{file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"},
{file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"},
{file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"},
{file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"},
{file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"},
{file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"},
{file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"},
{file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"},
{file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"},
{file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"},
{file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"},
{file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"},
{file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"},
{file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"},
{file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"},
{file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"},
{file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"},
{file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"},
{file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"},
{file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"},
{file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"},
{file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"},
{file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"},
{file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"},
{file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"},
{file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"},
{file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"},
{file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"},
{file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"},
{file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"},
{file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"},
{file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"},
{file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"},
{file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"},
{file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"},
{file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"},
{file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"},
{file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"},
{file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"},
{file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"},
{file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"},
{file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"},
]
[package.dependencies]
@ -4148,29 +4076,29 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.5.2"
version = "0.5.0"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.5.2-py3-none-linux_armv6l.whl", hash = "sha256:7bab8345df60f9368d5f4594bfb8b71157496b44c30ff035d1d01972e764d3be"},
{file = "ruff-0.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aa7acad382ada0189dbe76095cf0a36cd0036779607c397ffdea16517f535b1"},
{file = "ruff-0.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aec618d5a0cdba5592c60c2dee7d9c865180627f1a4a691257dea14ac1aa264d"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b62adc5ce81780ff04077e88bac0986363e4a3260ad3ef11ae9c14aa0e67ef"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc42ebf56ede83cb080a50eba35a06e636775649a1ffd03dc986533f878702a3"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15c6e9f88c67ffa442681365d11df38afb11059fc44238e71a9d9f1fd51de70"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d3de9a5960f72c335ef00763d861fc5005ef0644cb260ba1b5a115a102157251"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe5a968ae933e8f7627a7b2fc8893336ac2be0eb0aace762d3421f6e8f7b7f83"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04f54a9018f75615ae52f36ea1c5515e356e5d5e214b22609ddb546baef7132"},
{file = "ruff-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed02fb52e3741f0738db5f93e10ae0fb5c71eb33a4f2ba87c9a2fa97462a649"},
{file = "ruff-0.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3cf8fe659f6362530435d97d738eb413e9f090e7e993f88711b0377fbdc99f60"},
{file = "ruff-0.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:237a37e673e9f3cbfff0d2243e797c4862a44c93d2f52a52021c1a1b0899f846"},
{file = "ruff-0.5.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2a2949ce7c1cbd8317432ada80fe32156df825b2fd611688814c8557824ef060"},
{file = "ruff-0.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:481af57c8e99da92ad168924fd82220266043c8255942a1cb87958b108ac9335"},
{file = "ruff-0.5.2-py3-none-win32.whl", hash = "sha256:f1aea290c56d913e363066d83d3fc26848814a1fed3d72144ff9c930e8c7c718"},
{file = "ruff-0.5.2-py3-none-win_amd64.whl", hash = "sha256:8532660b72b5d94d2a0a7a27ae7b9b40053662d00357bb2a6864dd7e38819084"},
{file = "ruff-0.5.2-py3-none-win_arm64.whl", hash = "sha256:73439805c5cb68f364d826a5c5c4b6c798ded6b7ebaa4011f01ce6c94e4d5583"},
{file = "ruff-0.5.2.tar.gz", hash = "sha256:2c0df2d2de685433794a14d8d2e240df619b748fbe3367346baa519d8e6f1ca2"},
{file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"},
{file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"},
{file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"},
{file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"},
{file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"},
{file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"},
{file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"},
{file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"},
{file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"},
{file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"},
{file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"},
{file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"},
]
[[package]]
@ -4192,13 +4120,13 @@ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"]
[[package]]
name = "scim2-filter-parser"
version = "0.6.0"
version = "0.5.1"
description = "A customizable parser/transpiler for SCIM2.0 filters."
optional = false
python-versions = ">=3.8"
files = [
{file = "scim2_filter_parser-0.6.0-py3-none-any.whl", hash = "sha256:a8769b302b491b767f44c7ced3ecfa43feab08dae3d3dbb4823aac91e04c7abf"},
{file = "scim2_filter_parser-0.6.0.tar.gz", hash = "sha256:e4a7831cb9f70c5552f291e66c0e3cafad154bb686be899e68e24652d2503544"},
{file = "scim2_filter_parser-0.5.1-py3-none-any.whl", hash = "sha256:09338fd73389606961d1fd90a068c6f4ffe357a9509bc48adc1dbb70afc2821d"},
{file = "scim2_filter_parser-0.5.1.tar.gz", hash = "sha256:d2b88d11fbf000baca8e6b2057edb9bdf9827c4a34b172d05559b2b9f1994edf"},
]
[package.dependencies]
@ -4228,13 +4156,13 @@ websocket-client = ">=1.8.0"
[[package]]
name = "sentry-sdk"
version = "2.10.0"
version = "2.7.1"
description = "Python client for Sentry (https://sentry.io)"
optional = false
python-versions = ">=3.6"
files = [
{file = "sentry_sdk-2.10.0-py2.py3-none-any.whl", hash = "sha256:87b3d413c87d8e7f816cc9334bff255a83d8b577db2b22042651c30c19c09190"},
{file = "sentry_sdk-2.10.0.tar.gz", hash = "sha256:545fcc6e36c335faa6d6cda84669b6e17025f31efbf3b2211ec14efe008b75d1"},
{file = "sentry_sdk-2.7.1-py2.py3-none-any.whl", hash = "sha256:ef1b3d54eb715825657cd4bb3cb42bb4dc85087bac14c56b0fd8c21abd968c9a"},
{file = "sentry_sdk-2.7.1.tar.gz", hash = "sha256:25006c7e68b75aaa5e6b9c6a420ece22e8d7daec4b7a906ffd3a8607b67c037b"},
]
[package.dependencies]
@ -4402,18 +4330,19 @@ test = ["pytest"]
[[package]]
name = "setuptools"
version = "70.0.0"
version = "69.5.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"},
{file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"},
{file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"},
{file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "six"
@ -5369,18 +5298,18 @@ multidict = ">=4.0"
[[package]]
name = "zipp"
version = "3.19.1"
version = "3.18.1"
description = "Backport of pathlib-compatible object wrapper for zip files"
optional = false
python-versions = ">=3.8"
files = [
{file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"},
{file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"},
{file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"},
{file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"},
]
[package.extras]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
[[package]]
name = "zope-interface"
@ -5448,4 +5377,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "~3.12"
content-hash = "484d2f95c5c725b76ade4455d4416be3ad6d29b1721a9367a775ecc442c7cc4b"
content-hash = "f960013b56683ab42d82f8b49b2822dffc76046e3d22695ebb737b405a98dbaf"

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "authentik"
version = "2024.6.1"
version = "2024.6.0"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]
@ -32,7 +32,7 @@ select = [
"PL",
]
ignore = [
"DJ001", # Avoid using `null=True` on string-based fields,
"DJ001" # Avoid using `null=True` on string-based fields,
]
[tool.ruff.lint.pylint]
max-args = 7
@ -103,11 +103,10 @@ django-prometheus = "*"
django-redis = "*"
django-storages = { extras = ["s3"], version = "*" }
# See https://github.com/django-tenants/django-tenants/pull/997
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch = "authentik-fixes" }
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch="authentik-fixes" }
djangorestframework = "3.14.0"
djangorestframework-guardian = "*"
docker = "*"
drf-orjson-renderer = "*"
drf-spectacular = "*"
dumb-init = "*"
duo-client = "*"

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2024.6.1
version: 2024.6.0
description: Making authentication simple.
contact:
email: hello@goauthentik.io
@ -2682,6 +2682,10 @@ paths:
name: name
schema:
type: string
- in: query
name: only_with_launch_url
schema:
type: boolean
- name: ordering
required: false
in: query
@ -29993,10 +29997,6 @@ paths:
operationId: stages_password_list
description: PasswordStage Viewset
parameters:
- in: query
name: allow_show_password
schema:
type: boolean
- in: query
name: configure_flow
schema:
@ -32848,6 +32848,8 @@ components:
type: object
description: Challenge when a flow's active stage calls `stage_invalid()`.
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -32868,6 +32870,7 @@ components:
required:
- pending_user
- pending_user_avatar
- type
AlgEnum:
enum:
- rsa
@ -32956,6 +32959,8 @@ components:
description: Special challenge for apple-native authentication flow, which happens
on the client.
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -32980,6 +32985,7 @@ components:
- redirect_uri
- scope
- state
- type
Application:
type: object
description: Application Serializer
@ -33250,6 +33256,8 @@ components:
type: object
description: Duo Challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33277,6 +33285,7 @@ components:
- pending_user
- pending_user_avatar
- stage_uuid
- type
AuthenticatorDuoChallengeResponseRequest:
type: object
description: Pseudo class for duo response
@ -33409,6 +33418,8 @@ components:
type: object
description: SMS Setup challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33430,6 +33441,7 @@ components:
required:
- pending_user
- pending_user_avatar
- type
AuthenticatorSMSChallengeResponseRequest:
type: object
description: SMS Challenge response, device is set by get_response_instance
@ -33572,6 +33584,8 @@ components:
type: object
description: Static authenticator challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33595,6 +33609,7 @@ components:
- codes
- pending_user
- pending_user_avatar
- type
AuthenticatorStaticChallengeResponseRequest:
type: object
description: Pseudo class for static response
@ -33693,6 +33708,8 @@ components:
type: object
description: TOTP Setup challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33714,6 +33731,7 @@ components:
- config_url
- pending_user
- pending_user_avatar
- type
AuthenticatorTOTPChallengeResponseRequest:
type: object
description: TOTP Challenge response, device is set by get_response_instance
@ -33920,6 +33938,8 @@ components:
type: object
description: Authenticator challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33948,6 +33968,7 @@ components:
- device_challenges
- pending_user
- pending_user_avatar
- type
AuthenticatorValidationChallengeResponseRequest:
type: object
description: Challenge used for Code-based and WebAuthn authenticators
@ -33973,6 +33994,8 @@ components:
type: object
description: WebAuthn Challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -33995,6 +34018,7 @@ components:
- pending_user
- pending_user_avatar
- registration
- type
AuthenticatorWebAuthnChallengeResponseRequest:
type: object
description: WebAuthn Challenge response
@ -34122,6 +34146,8 @@ components:
type: object
description: Autosubmit challenge used to send and navigate a POST request
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -34143,6 +34169,7 @@ components:
type: string
required:
- attrs
- type
- url
BackendsEnum:
enum:
@ -34372,6 +34399,8 @@ components:
type: object
description: Site public key
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -34396,6 +34425,7 @@ components:
- pending_user
- pending_user_avatar
- site_key
- type
CaptchaChallengeResponseRequest:
type: object
description: Validate captcha token
@ -34626,6 +34656,12 @@ components:
required:
- certificate_data
- name
ChallengeChoices:
enum:
- native
- shell
- redirect
type: string
ChallengeTypes:
oneOf:
- $ref: '#/components/schemas/AccessDeniedChallenge'
@ -34758,6 +34794,8 @@ components:
type: object
description: Challenge info for consent screens
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -34791,6 +34829,7 @@ components:
- pending_user_avatar
- permissions
- token
- type
ConsentChallengeResponseRequest:
type: object
description: Consent challenge response, any valid response request is valid
@ -35239,6 +35278,8 @@ components:
type: object
description: Dummy challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -35254,6 +35295,7 @@ components:
type: string
required:
- name
- type
DummyChallengeResponseRequest:
type: object
description: Dummy challenge response
@ -35436,6 +35478,8 @@ components:
type: object
description: Email challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -35447,6 +35491,8 @@ components:
type: array
items:
$ref: '#/components/schemas/ErrorDetail'
required:
- type
EmailChallengeResponseRequest:
type: object
description: |-
@ -36272,6 +36318,9 @@ components:
Challenge class when an unhandled error occurs during a stage. Normal users
are shown an error message, superusers are shown a full stacktrace.
properties:
type:
type: string
default: native
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -36589,7 +36638,6 @@ components:
href:
type: string
readOnly: true
nullable: true
name:
type: string
readOnly: true
@ -37053,6 +37101,8 @@ components:
type: object
description: Identification challenges with all UI elements
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -37071,9 +37121,6 @@ components:
nullable: true
password_fields:
type: boolean
allow_show_password:
type: boolean
default: false
application_pre:
type: string
flow_designation:
@ -37097,6 +37144,7 @@ components:
- password_fields
- primary_action
- show_source_labels
- type
- user_fields
IdentificationChallengeResponseRequest:
type: object
@ -37156,7 +37204,7 @@ components:
format: uuid
nullable: true
description: When set, shows a password field, instead of showing the password
field as separate step.
field as seaprate step.
case_insensitive_matching:
type: boolean
description: When enabled, user fields are matched regardless of their casing.
@ -37224,7 +37272,7 @@ components:
format: uuid
nullable: true
description: When set, shows a password field, instead of showing the password
field as separate step.
field as seaprate step.
case_insensitive_matching:
type: boolean
description: When enabled, user fields are matched regardless of their casing.
@ -39115,6 +39163,8 @@ components:
type: object
description: OAuth Device code challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -39126,6 +39176,8 @@ components:
type: array
items:
$ref: '#/components/schemas/ErrorDetail'
required:
- type
OAuthDeviceCodeChallengeResponseRequest:
type: object
description: Response that includes the user-entered device code
@ -39142,6 +39194,8 @@ components:
type: object
description: Final challenge after user enters their code
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -39153,6 +39207,8 @@ components:
type: array
items:
$ref: '#/components/schemas/ErrorDetail'
required:
- type
OAuthDeviceCodeFinishChallengeResponseRequest:
type: object
description: Response that device has been authenticated and tab can be closed
@ -39445,9 +39501,6 @@ components:
allOf:
- $ref: '#/components/schemas/ServiceConnection'
readOnly: true
refresh_interval_s:
type: integer
readOnly: true
token_identifier:
type: string
description: Get Token identifier
@ -39469,7 +39522,6 @@ components:
- pk
- providers
- providers_obj
- refresh_interval_s
- service_connection_obj
- token_identifier
- type
@ -40943,6 +40995,8 @@ components:
type: object
description: Password challenge UI fields
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -40960,12 +41014,10 @@ components:
type: string
recovery_url:
type: string
allow_show_password:
type: boolean
default: false
required:
- pending_user
- pending_user_avatar
- type
PasswordChallengeResponseRequest:
type: object
description: Password challenge response
@ -41245,10 +41297,6 @@ components:
minimum: -2147483648
description: How many attempts a user has before the flow is canceled. To
lock the user out, use a reputation policy and a user_write stage.
allow_show_password:
type: boolean
description: When enabled, provides a 'show password' button with the password
input field.
required:
- backends
- component
@ -41285,10 +41333,6 @@ components:
minimum: -2147483648
description: How many attempts a user has before the flow is canceled. To
lock the user out, use a reputation policy and a user_write stage.
allow_show_password:
type: boolean
description: When enabled, provides a 'show password' button with the password
input field.
required:
- backends
- name
@ -42110,7 +42154,7 @@ components:
format: uuid
nullable: true
description: When set, shows a password field, instead of showing the password
field as separate step.
field as seaprate step.
case_insensitive_matching:
type: boolean
description: When enabled, user fields are matched regardless of their casing.
@ -42822,10 +42866,6 @@ components:
minimum: -2147483648
description: How many attempts a user has before the flow is canceled. To
lock the user out, use a reputation policy and a user_write stage.
allow_show_password:
type: boolean
description: When enabled, provides a 'show password' button with the password
input field.
PatchedPermissionAssignRequest:
type: object
description: Request to assign a new permission
@ -43868,6 +43908,8 @@ components:
type: object
description: Challenge shown to the user in identification stage
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -43886,6 +43928,7 @@ components:
required:
- client_id
- slug
- type
PlexAuthenticationChallengeResponseRequest:
type: object
description: Pseudo class for plex response
@ -44334,6 +44377,8 @@ components:
type: object
description: Initial challenge being sent, define fields
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -44351,6 +44396,7 @@ components:
$ref: '#/components/schemas/StagePrompt'
required:
- fields
- type
PromptChallengeResponseRequest:
type: object
description: |-
@ -45412,6 +45458,8 @@ components:
type: object
description: Challenge type to redirect the client
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -45427,6 +45475,7 @@ components:
type: string
required:
- to
- type
Reputation:
type: object
description: Reputation Serializer
@ -46909,6 +46958,8 @@ components:
type: object
description: challenge type to render HTML as-is
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -46924,6 +46975,7 @@ components:
type: string
required:
- body
- type
SignatureAlgorithmEnum:
enum:
- http://www.w3.org/2000/09/xmldsig#rsa-sha1
@ -48044,6 +48096,8 @@ components:
type: object
description: Empty challenge
properties:
type:
$ref: '#/components/schemas/ChallengeChoices'
flow_info:
$ref: '#/components/schemas/ContextualFlowInfo'
component:
@ -48062,6 +48116,7 @@ components:
required:
- pending_user
- pending_user_avatar
- type
UserLoginChallengeResponseRequest:
type: object
description: User login challenge

View File

@ -1,6 +1,5 @@
"""test OAuth Source"""
from json import loads
from pathlib import Path
from time import sleep
from typing import Any
@ -195,41 +194,3 @@ class TestSourceOAuth2(SeleniumTestCase):
self.driver.get(self.if_user_url("/settings"))
self.assert_user(User(username="foo", name="admin", email="admin@example.com"))
@retry()
@apply_blueprint(
"default/flow-default-authentication-flow.yaml",
"default/flow-default-invalidation-flow.yaml",
)
@apply_blueprint(
"default/flow-default-source-authentication.yaml",
"default/flow-default-source-enrollment.yaml",
"default/flow-default-source-pre-authentication.yaml",
)
def test_oauth_link(self):
"""test OAuth Source link OIDC"""
self.create_objects()
self.driver.get(self.live_server_url)
self.login()
self.driver.get(
self.url("authentik_sources_oauth:oauth-client-login", source_slug=self.slug)
)
# Now we should be at the IDP, wait for the login field
self.wait.until(ec.presence_of_element_located((By.ID, "login")))
self.driver.find_element(By.ID, "login").send_keys("admin@example.com")
self.driver.find_element(By.ID, "password").send_keys("password")
self.driver.find_element(By.ID, "password").send_keys(Keys.ENTER)
# Wait until we're logged in
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "button[type=submit]")))
self.driver.find_element(By.CSS_SELECTOR, "button[type=submit]").click()
self.driver.get(self.url("authentik_api:usersourceconnection-list") + "?format=json")
body_json = loads(self.driver.find_element(By.CSS_SELECTOR, "pre").text)
results = body_json["results"]
self.assertEqual(len(results), 1)
connection = results[0]
self.assertEqual(connection["source"]["slug"], self.slug)
self.assertEqual(connection["user"], self.user.pk)

View File

@ -10,17 +10,17 @@
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.16.1",
"@wdio/cli": "^8.39.1",
"@wdio/local-runner": "^8.39.1",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.39.0",
"@wdio/local-runner": "^8.39.0",
"@wdio/mocha-framework": "^8.39.0",
"@wdio/spec-reporter": "^8.39.0",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^1.0.3",
"eslint-plugin-sonarjs": "^0.25.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",
"prettier": "^3.3.2",
"ts-node": "^10.9.2",
"typescript": "^5.5.3",
"wdio-wait-for": "^3.0.11"
@ -326,9 +326,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.2.tgz",
"integrity": "sha512-0MGxAVt1m/ZK+LTJp/j0qF7Hz97D9O/FH9Ms3ltnyIdDD57cbb1ACIQTkbHvNXtWDv5TPq7w5Kq56+cNukbo7g==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@ -876,6 +876,12 @@
"@types/istanbul-lib-report": "*"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"node_modules/@types/mocha": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
@ -897,6 +903,12 @@
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"dev": true
},
"node_modules/@types/semver": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
"dev": true
},
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@ -943,20 +955,22 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz",
"integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
"integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "7.16.1",
"@typescript-eslint/type-utils": "7.16.1",
"@typescript-eslint/utils": "7.16.1",
"@typescript-eslint/visitor-keys": "7.16.1",
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "7.5.0",
"@typescript-eslint/type-utils": "7.5.0",
"@typescript-eslint/utils": "7.5.0",
"@typescript-eslint/visitor-keys": "7.5.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"ignore": "^5.2.4",
"natural-compare": "^1.4.0",
"ts-api-utils": "^1.3.0"
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -976,15 +990,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz",
"integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
"integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "7.16.1",
"@typescript-eslint/types": "7.16.1",
"@typescript-eslint/typescript-estree": "7.16.1",
"@typescript-eslint/visitor-keys": "7.16.1",
"@typescript-eslint/scope-manager": "7.5.0",
"@typescript-eslint/types": "7.5.0",
"@typescript-eslint/typescript-estree": "7.5.0",
"@typescript-eslint/visitor-keys": "7.5.0",
"debug": "^4.3.4"
},
"engines": {
@ -1004,13 +1018,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz",
"integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
"integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.16.1",
"@typescript-eslint/visitor-keys": "7.16.1"
"@typescript-eslint/types": "7.5.0",
"@typescript-eslint/visitor-keys": "7.5.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1021,15 +1035,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz",
"integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
"integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "7.16.1",
"@typescript-eslint/utils": "7.16.1",
"@typescript-eslint/typescript-estree": "7.5.0",
"@typescript-eslint/utils": "7.5.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1048,9 +1062,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz",
"integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
"integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
"dev": true,
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1061,19 +1075,19 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz",
"integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
"integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.16.1",
"@typescript-eslint/visitor-keys": "7.16.1",
"@typescript-eslint/types": "7.5.0",
"@typescript-eslint/visitor-keys": "7.5.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
"minimatch": "9.0.3",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1098,9 +1112,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@ -1113,15 +1127,18 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz",
"integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
"integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "7.16.1",
"@typescript-eslint/types": "7.16.1",
"@typescript-eslint/typescript-estree": "7.16.1"
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "7.5.0",
"@typescript-eslint/types": "7.5.0",
"@typescript-eslint/typescript-estree": "7.5.0",
"semver": "^7.5.4"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1135,13 +1152,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "7.16.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz",
"integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
"integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.16.1",
"eslint-visitor-keys": "^3.4.3"
"@typescript-eslint/types": "7.5.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@ -1172,15 +1189,15 @@
}
},
"node_modules/@wdio/cli": {
"version": "8.39.1",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.39.1.tgz",
"integrity": "sha512-CUze/nbOMzgSEp+Qo27dnM5IhlOPAiBJCPX3xO85/kjweqqxmAB1QBKww1Mz9YlNIXineaHrkgqlUQIvEqOJdQ==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.39.0.tgz",
"integrity": "sha512-kAd+8TYjJWRN6gZaRGiSu6Yj3k4+ULRt2NWAgNtGhnr0/Rwlr3j9bjAIhXGL574VqrH+rSnrevDdeGuLcZa1xg==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.1",
"@vitest/snapshot": "^1.2.1",
"@wdio/config": "8.39.0",
"@wdio/globals": "8.39.1",
"@wdio/globals": "8.39.0",
"@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0",
"@wdio/types": "8.39.0",
@ -1199,7 +1216,7 @@
"lodash.union": "^4.6.0",
"read-pkg-up": "10.0.0",
"recursive-readdir": "^2.2.3",
"webdriverio": "8.39.1",
"webdriverio": "8.39.0",
"yargs": "^17.7.2"
},
"bin": {
@ -1240,28 +1257,28 @@
}
},
"node_modules/@wdio/globals": {
"version": "8.39.1",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.39.1.tgz",
"integrity": "sha512-kNb1TlxI8Le/tsOiw7CMQcG0+ZGyxk9ZDO/PQLxkJvjo/q2QmiBcgaNMPuf+j1ABETcQK4bI7QtiT5uZ+f2AGA==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.39.0.tgz",
"integrity": "sha512-qZo6JjRCIOtdvba6fdSqj6b91TnWXD6rmamyud93FTqbcspnhBvr8lmgOs5wnslTKeeTTigCjpsT310b4/AyHA==",
"dev": true,
"engines": {
"node": "^16.13 || >=18"
},
"optionalDependencies": {
"expect-webdriverio": "^4.11.2",
"webdriverio": "8.39.1"
"webdriverio": "8.39.0"
}
},
"node_modules/@wdio/local-runner": {
"version": "8.39.1",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.39.1.tgz",
"integrity": "sha512-VYRD7pSkl5JTsYXroM65yb+vJVn9pFJf0XZMB7Xj+WVUqGXuVkZ+XybsQetUlhruXvHIsPdiFj12V1tMyaUHrQ==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.39.0.tgz",
"integrity": "sha512-TSGJVVWqshH7IO13OKw7G/364q3FczZDEh4h6bYe+GAs91KpZrEhZanyALgjh5F3crWtlffX+GA2HUwpi8X0sA==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.38.0",
"@wdio/repl": "8.24.12",
"@wdio/runner": "8.39.1",
"@wdio/runner": "8.39.0",
"@wdio/types": "8.39.0",
"async-exit-hook": "^2.0.1",
"split2": "^4.1.0",
@ -1350,14 +1367,14 @@
}
},
"node_modules/@wdio/runner": {
"version": "8.39.1",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.39.1.tgz",
"integrity": "sha512-hCGI+TSAyb14UtdDjswI5AAdW1CZMi6di+rDZ6ml43hQyHc6sw+74CXI8dwoJ29dcTzbg7QCJZZXV1qMn0kh2w==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.39.0.tgz",
"integrity": "sha512-M1ixrrCtuwxHVzwsOKGMWBZCteafV0ztoS9+evMWGQtj0ZEsmhjAhWR3n2nZftt24vWOs+eNLGe2p+IO9Sm9bA==",
"dev": true,
"dependencies": {
"@types/node": "^20.11.28",
"@wdio/config": "8.39.0",
"@wdio/globals": "8.39.1",
"@wdio/globals": "8.39.0",
"@wdio/logger": "8.38.0",
"@wdio/types": "8.39.0",
"@wdio/utils": "8.39.0",
@ -1365,7 +1382,7 @@
"expect-webdriverio": "^4.12.0",
"gaze": "^1.1.3",
"webdriver": "8.39.0",
"webdriverio": "8.39.1"
"webdriverio": "8.39.0"
},
"engines": {
"node": "^16.13 || >=18"
@ -3110,15 +3127,15 @@
}
},
"node_modules/eslint-plugin-sonarjs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-1.0.3.tgz",
"integrity": "sha512-6s41HLPYPyDrp+5+7Db5yFYbod6h9pC7yx+xfcNwHRcLe1EZwbbQT/tdOAkR7ekVUkNGEvN3GmYakIoQUX7dEg==",
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.25.1.tgz",
"integrity": "sha512-5IOKvj/GMBNqjxBdItfotfRHo7w48496GOu1hxdeXuD0mB1JBlDCViiLHETDTfA8pDAVSBimBEQoetRXYceQEw==",
"dev": true,
"engines": {
"node": ">=16"
},
"peerDependencies": {
"eslint": "^8.0.0 || ^9.0.0"
"eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/eslint-scope": {
@ -4433,9 +4450,9 @@
]
},
"node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
@ -6891,9 +6908,9 @@
}
},
"node_modules/prettier": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@ -7801,10 +7818,13 @@
"dev": true
},
"node_modules/semver": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
@ -7812,6 +7832,18 @@
"node": ">=10"
}
},
"node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/serialize-error": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.2.tgz",
@ -8448,12 +8480,12 @@
}
},
"node_modules/ts-api-utils": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
"integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
"dev": true,
"engines": {
"node": ">=16"
"node": ">=16.13.0"
},
"peerDependencies": {
"typescript": ">=4.2.0"
@ -8959,9 +8991,9 @@
}
},
"node_modules/webdriverio": {
"version": "8.39.1",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.1.tgz",
"integrity": "sha512-dPwLgLNtP+l4vnybz+YFxxH8nBKOP7j6VVzKtfDyTLDQg9rz3U8OA4xMMQCBucnrVXy3KcKxGqlnMa+c4IfWCQ==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz",
"integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
@ -9255,6 +9287,12 @@
"node": ">=10"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",

View File

@ -4,17 +4,17 @@
"type": "module",
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.16.1",
"@wdio/cli": "^8.39.1",
"@wdio/local-runner": "^8.39.1",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.39.0",
"@wdio/local-runner": "^8.39.0",
"@wdio/mocha-framework": "^8.39.0",
"@wdio/spec-reporter": "^8.39.0",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^1.0.3",
"eslint-plugin-sonarjs": "^0.25.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",
"prettier": "^3.3.2",
"ts-node": "^10.9.2",
"typescript": "^5.5.3",
"wdio-wait-for": "^3.0.11"

View File

@ -53,7 +53,7 @@ type Pair = [string, string];
// Define a getter for each provider type in the radio button collection.
const providerValues: Pair[] = [
["oauth2Provider", "oauth2Provider"],
["oauth2provider", "oauth2Provider"],
["ldapprovider", "ldapProvider"],
["proxyprovider-proxy", "proxyProviderProxy"],
["proxyprovider-forwardsingle", "proxyProviderForwardsingle"],
@ -66,7 +66,7 @@ providerValues.forEach(([value, name]: Pair) => {
Object.defineProperties(ApplicationWizardView.prototype, {
[name]: {
get: function () {
return this.providerList.$(`>>>div[data-testid=wizard-provider-${value}]`);
return this.providerList.$(`>>>input[value="${value}"]`);
},
},
});

View File

@ -4,9 +4,9 @@ import { $ } from "@wdio/globals";
export class ForwardProxyForm extends Page {
async setAuthorizationFlow(selector: string) {
await this.searchSelect(
'[name="authorizationFlow"]',
'>>>ak-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}

View File

@ -3,9 +3,9 @@ import Page from "../page.js";
export class LdapForm extends Page {
async setBindFlow(selector: string) {
await this.searchSelect(
"[name=authorizationFlow]",
'>>>ak-branded-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}
}

View File

@ -4,9 +4,9 @@ import { $ } from "@wdio/globals";
export class OauthForm extends Page {
async setAuthorizationFlow(selector: string) {
await this.searchSelect(
'[name="authorizationFlow"]',
'>>>ak-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}

View File

@ -3,9 +3,9 @@ import Page from "../page.js";
export class RadiusForm extends Page {
async setAuthenticationFlow(selector: string) {
await this.searchSelect(
'[name="authorizationFlow"]',
'>>>ak-branded-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}
}

View File

@ -4,9 +4,9 @@ import { $ } from "@wdio/globals";
export class SamlForm extends Page {
async setAuthorizationFlow(selector: string) {
await this.searchSelect(
'[name="authorizationFlow"]',
'>>>ak-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}

View File

@ -4,9 +4,9 @@ import { $ } from "@wdio/globals";
export class TransparentProxyForm extends Page {
async setAuthorizationFlow(selector: string) {
await this.searchSelect(
'[name="authorizationFlow"]',
'>>>ak-flow-search[name="authorizationFlow"] input[type="text"]',
"authorizationFlow",
`div*=${selector}`,
`button*=${selector}`,
);
}

View File

@ -1,7 +1,6 @@
import Page from "./page.js";
import UserLibraryPage from "./user-library.page.js";
import { $ } from "@wdio/globals";
import { and, or, presenceOf, textToBePresentInElement } from "wdio-wait-for";
/**
* sub page containing specific selectors and methods for a specific page
@ -49,14 +48,6 @@ class LoginPage extends Page {
await this.pause();
await this.password(password);
await this.pause();
const redirect = await $(">>>a[type=submit]");
await browser.waitUntil(or(presenceOf(redirect), presenceOf(UserLibraryPage.pageHeader)));
if (await redirect.isExisting()) {
await redirect.click();
}
await this.pause(">>>div.header h1");
return UserLibraryPage;
}

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