Compare commits

...

31 Commits

Author SHA1 Message Date
a35cb42a68 release: 2023.8.7 2024-01-29 17:44:35 +01:00
9591c4dc10 security: fix CVE-2024-23647 (cherry-pick #8345) (#8346)
security: fix CVE-2024-23647 (#8345)

* security: fix CVE-2024-23647



* add tests



* add website



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2024-01-29 17:42:07 +01:00
2a3d2cd262 release: 2023.8.6 2024-01-09 18:44:21 +01:00
d9aab79c62 providers/oauth2: fix CVE-2024-21637 (cherry-pick #8104) (#8106)
* providers/oauth2: fix CVE-2024-21637 (#8104)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update changelog

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2024-01-09 18:43:56 +01:00
1516fe86da release: 2023.8.5 2023-11-21 19:51:16 +01:00
abad6c181f ci: fix permissions for release pipeline to publish binaries (cherry-pick #7512) (#7621)
ci: fix permissions for release pipeline to publish binaries (#7512)

ci: fix permissions

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2023-11-21 19:51:11 +01:00
312eb70349 ci: explicitly give write permissions to packages (cherry-pick #7428) (#7430)
ci: explicitly give write permissions to packages (#7428)

* ci: explicitly give write permissions to packages



* run full CI on cherry-picks



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2023-11-21 19:51:06 +01:00
3af77ab382 security: fix CVE-2023-48228 (cherry-pick #7666) (#7669)
security: fix CVE-2023-48228 (#7666)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2023-11-21 18:13:50 +01:00
72d67f65e5 release: 2023.8.4 2023-10-28 21:44:15 +02:00
ea75741ec2 security: fix oobe-flow reuse when akadmin is deleted (#7361)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	website/docs/releases/2023/v2023.10.md
2023-10-28 21:26:53 +02:00
aaa9b398f4 sources/ldap: fix inverted interpretation of FreeIPA nsaccountlock (cherry-pick #6877) (#6879)
sources/ldap: fix inverted interpretation of FreeIPA nsaccountlock (#6877)

sources/ldap: fix inverted interpretation of nsaccountlock

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
2023-09-13 19:50:48 +02:00
d54d01b118 providers/saml: set WantAuthnRequestsSigned in metadata (cherry-pick #6851) (#6880)
providers/saml: set WantAuthnRequestsSigned in metadata (#6851)

Co-authored-by: Jens L <jens@goauthentik.io>
2023-09-13 19:50:41 +02:00
f885f8c039 release: 2023.8.3 2023-09-11 18:55:08 +02:00
b5b33ce8e9 website/docs: prepare 2023.8.3 release notes (#6843)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-11 18:54:58 +02:00
ec5bd550c7 core: remove celery's duplicate max_tasks_per_child (#6840)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-11 18:15:17 +02:00
fe02720f8d providers/scim: check that a provider exists before starting scim task (#6841)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-11 18:15:12 +02:00
67bd622aa4 web/admin: fix flow-search not being able to unset (#6838)
similar to https://github.com/goauthentik/authentik/pull/6767

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-11 14:16:52 +02:00
dd18f9cd30 sources/ldap: dont prefetch useless items (#6812)
sources/ldap: Fixed fetching of useless data into redis
2023-09-11 12:44:49 +02:00
d36574fc1a sources/ldap: fix task timeout for ldap_sync_all and ldap_sync_single (#6809)
* sources/ldap: fix task timeout for ldap_sync_all and ldap_sync_single

* ldap_sync_all runs tasks async so doesn't need longer timeouts

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* bump time more as we run some tasks in serial and add more leeway

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-09-11 12:44:40 +02:00
f2754d278f root: lock node to 20.5 (#6776)
* root: lock node to 20.5

there are apparently some breaking issues in 20.6 with babel https://github.com/babel/babel/issues/15927

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use same version of setup-node everywhere

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	.github/workflows/ci-web.yml
#	.github/workflows/ci-website.yml
2023-09-06 14:01:05 +02:00
25ac04f4e5 web/admin: fix not being able to unset certificates (#6767)
* web: fix 6742: empty web certificate request needs to return null, not undefined

This replaces the `undefined` setting of the certificate search wrapper to
`null` when the admin requests no certificate.

* only set singleton if we don't have an instance

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 14:00:32 +02:00
ae91689fd8 policies/reputation: require either check to be enabled (#6764)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 14:00:29 +02:00
aa209efa90 stages/password: fix failed_attempts_before_cancel allowing one too m… (#6763)
* stages/password: fix failed_attempts_before_cancel allowing one too many tries

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 14:00:24 +02:00
7e9e2ec53d web: don't import entire SourceViewPage in flow and user interface (#6761)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 14:00:16 +02:00
77e7c31567 core: bump django from 4.2.4 to 4.2.5 (#6751)
Bumps [django](https://github.com/django/django) from 4.2.4 to 4.2.5.
- [Commits](https://github.com/django/django/compare/4.2.4...4.2.5)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-06 13:59:54 +02:00
4b20409a91 sources/ldap: fix FreeIPA nsaccountlock sync (#6745)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 13:59:36 +02:00
19e04d7837 core: bump celery from 5.3.1 to 5.3.4
Bumps [celery](https://github.com/celery/celery) from 5.3.1 to 5.3.4.
- [Release notes](https://github.com/celery/celery/releases)
- [Changelog](https://github.com/celery/celery/blob/main/Changelog.rst)
- [Commits](https://github.com/celery/celery/compare/v5.3.1...v5.3.4)

---
updated-dependencies:
- dependency-name: celery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 13:59:32 +02:00
352ec55729 root: fix broken celery dependency (#6744)
celery 5.3.3 was yanked so downgrade

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 13:59:28 +02:00
5333050e5d core: compile backend translations (#6739)
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2023-09-06 13:59:23 +02:00
9c448d74f7 web/admin: fix application icon size (#6738)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 13:59:19 +02:00
05a4649282 web: replace ampersand (#6737)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-09-06 13:59:02 +02:00
74 changed files with 1253 additions and 532 deletions

View File

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

View File

@ -23,7 +23,7 @@ runs:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- name: Setup dependencies

View File

@ -11,6 +11,7 @@ on:
pull_request:
branches:
- main
- version-*
env:
POSTGRES_DB: authentik
@ -184,6 +185,9 @@ jobs:
build:
needs: ci-core-mark
runs-on: ubuntu-latest
permissions:
# Needed to upload contianer images to ghcr.io
packages: write
timeout-minutes: 120
steps:
- uses: actions/checkout@v3
@ -229,6 +233,9 @@ jobs:
build-arm64:
needs: ci-core-mark
runs-on: ubuntu-latest
permissions:
# Needed to upload contianer images to ghcr.io
packages: write
timeout-minutes: 120
steps:
- uses: actions/checkout@v3

View File

@ -9,6 +9,7 @@ on:
pull_request:
branches:
- main
- version-*
jobs:
lint-golint:
@ -63,6 +64,9 @@ jobs:
- ldap
- radius
runs-on: ubuntu-latest
permissions:
# Needed to upload contianer images to ghcr.io
packages: write
steps:
- uses: actions/checkout@v3
with:
@ -120,9 +124,9 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version-file: "go.mod"
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- name: Generate API

View File

@ -9,15 +9,16 @@ on:
pull_request:
branches:
- main
- version-*
jobs:
lint-eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- working-directory: web/
@ -30,10 +31,10 @@ jobs:
lint-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- working-directory: web/
@ -46,10 +47,10 @@ jobs:
lint-prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- working-directory: web/
@ -62,10 +63,10 @@ jobs:
lint-lit-analyse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- working-directory: web/
@ -94,10 +95,10 @@ jobs:
- ci-web-mark
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- working-directory: web/

View File

@ -9,15 +9,16 @@ on:
pull_request:
branches:
- main
- version-*
jobs:
lint-prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/
@ -28,10 +29,10 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/
@ -49,10 +50,10 @@ jobs:
- build
- build-docs-only
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.8.1
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/

View File

@ -6,6 +6,7 @@ on:
workflow_dispatch:
permissions:
# Needed to be able to push to the next branch
contents: write
jobs:

View File

@ -7,6 +7,9 @@ on:
jobs:
build-server:
runs-on: ubuntu-latest
permissions:
# Needed to upload contianer images to ghcr.io
packages: write
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
@ -47,6 +50,9 @@ jobs:
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
build-outpost:
runs-on: ubuntu-latest
permissions:
# Needed to upload contianer images to ghcr.io
packages: write
strategy:
fail-fast: false
matrix:
@ -96,6 +102,9 @@ jobs:
build-outpost-binary:
timeout-minutes: 120
runs-on: ubuntu-latest
permissions:
# Needed to upload binaries to the release
contents: write
strategy:
fail-fast: false
matrix:
@ -110,9 +119,9 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version-file: "go.mod"
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
cache: "npm"
cache-dependency-path: web/package-lock.json
- name: Build web

View File

@ -6,8 +6,8 @@ on:
workflow_dispatch:
permissions:
# Needed to update issues and PRs
issues: write
pull-requests: write
jobs:
stale:

View File

@ -17,9 +17,9 @@ jobs:
- uses: actions/checkout@v3
with:
token: ${{ steps.generate_token.outputs.token }}
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "20.5"
registry-url: "https://registry.npmjs.org"
- name: Generate API Client
run: make gen-client-ts

View File

@ -1,5 +1,5 @@
# Stage 1: Build website
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as website-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:20.5 as website-builder
COPY ./website /work/website/
COPY ./blueprints /work/blueprints/
@ -10,7 +10,7 @@ WORKDIR /work/website
RUN npm ci --include=dev && npm run build-docs-only
# Stage 2: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:20.5 as web-builder
COPY ./web /work/web/
COPY ./website /work/website/

View File

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

View File

@ -26,7 +26,6 @@ class Command(BaseCommand):
no_color=False,
quiet=True,
optimization="fair",
max_tasks_per_child=1,
autoscale=(3, 1),
task_events=True,
beat=True,

View File

@ -0,0 +1,25 @@
# Generated by Django 4.2.6 on 2023-10-10 17:18
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("authentik_flows", "0025_alter_flowstagebinding_evaluate_on_plan_and_more"),
]
operations = [
migrations.AlterModelOptions(
name="flow",
options={
"permissions": [
("export_flow", "Can export a Flow"),
("inspect_flow", "Can inspect a Flow's execution"),
("view_flow_cache", "View Flow's cache metrics"),
("clear_flow_cache", "Clear Flow's cache metrics"),
],
"verbose_name": "Flow",
"verbose_name_plural": "Flows",
},
),
]

View File

@ -0,0 +1,34 @@
# Generated by Django 4.2.6 on 2023-10-28 14:24
from django.apps.registry import Apps
from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def set_oobe_flow_authentication(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from guardian.shortcuts import get_anonymous_user
Flow = apps.get_model("authentik_flows", "Flow")
User = apps.get_model("authentik_core", "User")
db_alias = schema_editor.connection.alias
users = User.objects.using(db_alias).exclude(username="akadmin")
try:
users = users.exclude(pk=get_anonymous_user().pk)
# pylint: disable=broad-except
except Exception: # nosec
pass
if users.exists():
Flow.objects.filter(slug="initial-setup").update(authentication="require_superuser")
class Migration(migrations.Migration):
dependencies = [
("authentik_flows", "0026_alter_flow_options"),
]
operations = [
migrations.RunPython(set_oobe_flow_authentication),
]

View File

@ -1,5 +1,7 @@
"""Reputation policy API Views"""
from django.utils.translation import gettext_lazy as _
from rest_framework import mixins
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet
@ -11,6 +13,11 @@ from authentik.policies.reputation.models import Reputation, ReputationPolicy
class ReputationPolicySerializer(PolicySerializer):
"""Reputation Policy Serializer"""
def validate(self, attrs: dict) -> dict:
if not attrs.get("check_ip", False) and not attrs.get("check_username", False):
raise ValidationError(_("Either IP or Username must be checked"))
return super().validate(attrs)
class Meta:
model = ReputationPolicy
fields = PolicySerializer.Meta.fields + [

View File

@ -3,6 +3,8 @@ from django.core.cache import cache
from django.test import RequestFactory, TestCase
from authentik.core.models import User
from authentik.lib.generators import generate_id
from authentik.policies.reputation.api import ReputationPolicySerializer
from authentik.policies.reputation.models import CACHE_KEY_PREFIX, Reputation, ReputationPolicy
from authentik.policies.reputation.tasks import save_reputation
from authentik.policies.types import PolicyRequest
@ -61,3 +63,8 @@ class TestReputationPolicy(TestCase):
name="reputation-test", threshold=0
)
self.assertTrue(policy.passes(request).passing)
def test_api(self):
"""Test API Validation"""
no_toggle = ReputationPolicySerializer(data={"name": generate_id(), "threshold": -5})
self.assertFalse(no_toggle.is_valid())

View File

@ -85,6 +85,25 @@ class TestAuthorize(OAuthTestCase):
)
OAuthAuthorizationParams.from_request(request)
def test_blocked_redirect_uri(self):
"""test missing/invalid redirect URI"""
OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=create_test_flow(),
redirect_uris="data:local.invalid",
)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "data:localhost",
},
)
OAuthAuthorizationParams.from_request(request)
def test_invalid_redirect_uri_empty(self):
"""test missing/invalid redirect URI"""
provider = OAuth2Provider.objects.create(

View File

@ -0,0 +1,258 @@
"""Test token view"""
from base64 import b64encode, urlsafe_b64encode
from hashlib import sha256
from django.test import RequestFactory
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
from authentik.providers.oauth2.tests.utils import OAuthTestCase
class TestTokenPKCE(OAuthTestCase):
"""Test token view"""
def setUp(self) -> None:
super().setUp()
self.factory = RequestFactory()
self.app = Application.objects.create(name=generate_id(), slug="test")
def test_pkce_missing_in_authorize(self):
"""Test PKCE with code_challenge in authorize request
and missing verifier in token request"""
flow = create_test_flow()
provider = OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=flow,
redirect_uris="foo://localhost",
access_code_validity="seconds=100",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_id()
user = create_test_admin_user()
self.client.force_login(user)
challenge = generate_id()
header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode()
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "code",
"client_id": "test",
"state": state,
"redirect_uri": "foo://localhost",
"code_challenge": challenge,
"code_challenge_method": "S256",
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
self.assertJSONEqual(
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
# Missing the code_verifier here
"redirect_uri": "foo://localhost",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
self.assertJSONEqual(
response.content,
{
"error": "invalid_grant",
"error_description": (
"The provided authorization grant or refresh token is invalid, expired, "
"revoked, does not match the redirection URI used in the authorization "
"request, or was issued to another client"
),
},
)
self.assertEqual(response.status_code, 400)
def test_pkce_missing_in_token(self):
"""Test PKCE with missing code_challenge in authorization request but verifier
set in token request"""
flow = create_test_flow()
provider = OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=flow,
redirect_uris="foo://localhost",
access_code_validity="seconds=100",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_id()
user = create_test_admin_user()
self.client.force_login(user)
header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode()
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "code",
"client_id": "test",
"state": state,
"redirect_uri": "foo://localhost",
# "code_challenge": challenge,
# "code_challenge_method": "S256",
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
self.assertJSONEqual(
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
"code_verifier": generate_id(),
"redirect_uri": "foo://localhost",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
self.assertJSONEqual(
response.content,
{
"error": "invalid_grant",
"error_description": (
"The provided authorization grant or refresh token is invalid, expired, "
"revoked, does not match the redirection URI used in the authorization "
"request, or was issued to another client"
),
},
)
self.assertEqual(response.status_code, 400)
def test_pkce_correct_s256(self):
"""Test full with pkce"""
flow = create_test_flow()
provider = OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=flow,
redirect_uris="foo://localhost",
access_code_validity="seconds=100",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_id()
user = create_test_admin_user()
self.client.force_login(user)
verifier = generate_id()
challenge = (
urlsafe_b64encode(sha256(verifier.encode("ascii")).digest())
.decode("utf-8")
.replace("=", "")
)
header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode()
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "code",
"client_id": "test",
"state": state,
"redirect_uri": "foo://localhost",
"code_challenge": challenge,
"code_challenge_method": "S256",
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
self.assertJSONEqual(
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
"code_verifier": verifier,
"redirect_uri": "foo://localhost",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
self.assertEqual(response.status_code, 200)
def test_pkce_correct_plain(self):
"""Test full with pkce"""
flow = create_test_flow()
provider = OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=flow,
redirect_uris="foo://localhost",
access_code_validity="seconds=100",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_id()
user = create_test_admin_user()
self.client.force_login(user)
verifier = generate_id()
header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode()
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "code",
"client_id": "test",
"state": state,
"redirect_uri": "foo://localhost",
"code_challenge": verifier,
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
self.assertJSONEqual(
response.content.decode(),
{
"component": "xak-flow-redirect",
"type": ChallengeTypes.REDIRECT.value,
"to": f"foo://localhost?code={code.code}&state={state}",
},
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
"code_verifier": verifier,
"redirect_uri": "foo://localhost",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
self.assertEqual(response.status_code, 200)

View File

@ -74,6 +74,7 @@ PLAN_CONTEXT_PARAMS = "goauthentik.io/providers/oauth2/params"
SESSION_KEY_LAST_LOGIN_UID = "authentik/providers/oauth2/last_login_uid"
ALLOWED_PROMPT_PARAMS = {PROMPT_NONE, PROMPT_CONSENT, PROMPT_LOGIN}
FORBIDDEN_URI_SCHEMES = {"javascript", "data", "vbscript"}
@dataclass(slots=True)
@ -174,6 +175,10 @@ class OAuthAuthorizationParams:
self.check_scope()
self.check_nonce()
self.check_code_challenge()
if self.request:
raise AuthorizeError(
self.redirect_uri, "request_not_supported", self.grant_type, self.state
)
def check_redirect_uri(self):
"""Redirect URI validation."""
@ -211,10 +216,9 @@ class OAuthAuthorizationParams:
expected=allowed_redirect_urls,
)
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
if self.request:
raise AuthorizeError(
self.redirect_uri, "request_not_supported", self.grant_type, self.state
)
# Check against forbidden schemes
if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
def check_scope(self):
"""Ensure openid scope is set in Hybrid flows, or when requesting an id_token"""

View File

@ -6,6 +6,7 @@ from hashlib import sha256
from re import error as RegexError
from re import fullmatch
from typing import Any, Optional
from urllib.parse import urlparse
from django.http import HttpRequest, HttpResponse
from django.utils import timezone
@ -53,6 +54,7 @@ from authentik.providers.oauth2.models import (
RefreshToken,
)
from authentik.providers.oauth2.utils import TokenResponse, cors_allow, extract_client_auth
from authentik.providers.oauth2.views.authorize import FORBIDDEN_URI_SCHEMES
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
@ -204,6 +206,10 @@ class TokenParams:
).from_http(request)
raise TokenError("invalid_client")
# Check against forbidden schemes
if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
raise TokenError("invalid_request")
self.authorization_code = AuthorizationCode.objects.filter(code=raw_code).first()
if not self.authorization_code:
LOGGER.warning("Code does not exist", code=raw_code)
@ -221,7 +227,10 @@ class TokenParams:
raise TokenError("invalid_grant")
# Validate PKCE parameters.
if self.code_verifier:
if self.authorization_code.code_challenge:
# Authorization code had PKCE but we didn't get one
if not self.code_verifier:
raise TokenError("invalid_grant")
if self.authorization_code.code_challenge_method == PKCE_METHOD_S256:
new_code_challenge = (
urlsafe_b64encode(sha256(self.code_verifier.encode("ascii")).digest())
@ -234,6 +243,10 @@ class TokenParams:
if new_code_challenge != self.authorization_code.code_challenge:
LOGGER.warning("Code challenge not matching")
raise TokenError("invalid_grant")
# Token request had a code_verifier but code did not have a code challenge
# Prevent downgrade
if not self.authorization_code.code_challenge and self.code_verifier:
raise TokenError("invalid_grant")
def __post_init_refresh(self, raw_token: str, request: HttpRequest):
if not raw_token:

View File

@ -171,6 +171,8 @@ class MetadataProcessor:
entity_descriptor, f"{{{NS_SAML_METADATA}}}IDPSSODescriptor"
)
idp_sso_descriptor.attrib["protocolSupportEnumeration"] = NS_SAML_PROTOCOL
if self.provider.verification_kp:
idp_sso_descriptor.attrib["WantAuthnRequestsSigned"] = "true"
signing_descriptor = self.get_signing_key_descriptor()
if signing_descriptor is not None:

View File

@ -12,7 +12,7 @@ from authentik.lib.xml import lxml_from_string
from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.processors.metadata import MetadataProcessor
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
from authentik.sources.saml.processors.constants import NS_MAP
from authentik.sources.saml.processors.constants import NS_MAP, NS_SAML_METADATA
class TestServiceProviderMetadataParser(TestCase):
@ -55,6 +55,24 @@ class TestServiceProviderMetadataParser(TestCase):
schema = etree.XMLSchema(etree.parse("schemas/saml-schema-metadata-2.0.xsd")) # nosec
self.assertTrue(schema.validate(metadata))
def test_schema_want_authn_requests_signed(self):
"""Test metadata generation with WantAuthnRequestsSigned"""
cert = create_test_cert()
provider = SAMLProvider.objects.create(
name=generate_id(),
authorization_flow=self.flow,
verification_kp=cert,
)
Application.objects.create(
name=generate_id(),
slug=generate_id(),
provider=provider,
)
request = self.factory.get("/")
metadata = lxml_from_string(MetadataProcessor(provider, request).build_entity_descriptor())
idp_sso_descriptor = metadata.findall(f"{{{NS_SAML_METADATA}}}IDPSSODescriptor")[0]
self.assertEqual(idp_sso_descriptor.attrib["WantAuthnRequestsSigned"], "true")
def test_simple(self):
"""Test simple metadata without Signing"""
metadata = ServiceProviderMetadataParser().parse(load_fixture("fixtures/simple.xml"))

View File

@ -23,6 +23,8 @@ def post_save_provider(sender: type[Model], instance, created: bool, **_):
@receiver(post_save, sender=Group)
def post_save_scim(sender: type[Model], instance: User | Group, created: bool, **_):
"""Post save handler"""
if not SCIMProvider.objects.filter(backchannel_application__isnull=False).exists():
return
scim_signal_direct.delay(class_to_path(instance.__class__), instance.pk, PatchOp.add.value)
@ -30,6 +32,8 @@ def post_save_scim(sender: type[Model], instance: User | Group, created: bool, *
@receiver(pre_delete, sender=Group)
def pre_delete_scim(sender: type[Model], instance: User | Group, **_):
"""Pre-delete handler"""
if not SCIMProvider.objects.filter(backchannel_application__isnull=False).exists():
return
scim_signal_direct.delay(class_to_path(instance.__class__), instance.pk, PatchOp.remove.value)
@ -40,6 +44,8 @@ def m2m_changed_scim(
"""Sync group membership"""
if action not in ["post_add", "post_remove"]:
return
if not SCIMProvider.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
if reverse:

View File

@ -18,6 +18,9 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
return "groups"
def get_objects(self, **kwargs) -> Generator:
if not self._source.sync_groups:
self.message("Group syncing is disabled for this Source")
return iter(())
return self.search_paginator(
search_base=self.base_dn_groups,
search_filter=self._source.group_object_filter,

View File

@ -24,6 +24,9 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer):
return "membership"
def get_objects(self, **kwargs) -> Generator:
if not self._source.sync_groups:
self.message("Group syncing is disabled for this Source")
return iter(())
return self.search_paginator(
search_base=self.base_dn_groups,
search_filter=self._source.group_object_filter,

View File

@ -20,6 +20,9 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer):
return "users"
def get_objects(self, **kwargs) -> Generator:
if not self._source.sync_users:
self.message("User syncing is disabled for this Source")
return iter(())
return self.search_paginator(
search_base=self.base_dn_users,
search_filter=self._source.user_object_filter,

View File

@ -45,7 +45,13 @@ class FreeIPA(BaseLDAPSynchronizer):
# 389-ds and this will trigger regardless
if "nsaccountlock" not in attributes:
return
is_active = attributes.get("nsaccountlock", False)
# For some reason, nsaccountlock is not defined properly in the schema as bool
# hence we get it as a list of strings
_is_locked = str(self._flatten(attributes.get("nsaccountlock", ["FALSE"])))
# So we have to attempt to convert it to a bool
is_locked = _is_locked.lower() == "true"
# And then invert it since freeipa saves locked and we save active
is_active = not is_locked
if is_active != user.is_active:
user.is_active = is_active
user.save()

View File

@ -33,7 +33,13 @@ def ldap_sync_all():
ldap_sync_single(source.pk)
@CELERY_APP.task()
@CELERY_APP.task(
# We take the configured hours timeout time by 2.5 as we run user and
# group in parallel and then membership, so 2x is to cover the serial tasks,
# and 0.5x on top of that to give some more leeway
soft_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 2.5,
task_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 2.5,
)
def ldap_sync_single(source_pk: str):
"""Sync a single source"""
source: LDAPSource = LDAPSource.objects.filter(pk=source_pk).first()

View File

@ -0,0 +1,111 @@
"""ldap testing utils"""
from ldap3 import MOCK_SYNC, OFFLINE_DS389_1_3_3, Connection, Server
def mock_freeipa_connection(password: str) -> Connection:
"""Create mock FreeIPA-ish connection"""
server = Server("my_fake_server", get_info=OFFLINE_DS389_1_3_3)
_pass = "foo" # noqa # nosec
connection = Connection(
server,
user="cn=my_user,dc=goauthentik,dc=io",
password=_pass,
client_strategy=MOCK_SYNC,
)
# Entry for password checking
connection.strategy.add_entry(
"cn=user,ou=users,dc=goauthentik,dc=io",
{
"name": "test-user",
"uid": "unique-test-group",
"objectClass": "person",
"displayName": "Erin M. Hagens",
},
)
connection.strategy.add_entry(
"cn=group1,ou=groups,dc=goauthentik,dc=io",
{
"cn": "group1",
"uid": "unique-test-group",
"objectClass": "groupOfNames",
"member": ["cn=user0,ou=users,dc=goauthentik,dc=io"],
},
)
# Group without SID
connection.strategy.add_entry(
"cn=group2,ou=groups,dc=goauthentik,dc=io",
{
"cn": "group2",
"objectClass": "groupOfNames",
},
)
connection.strategy.add_entry(
"cn=user0,ou=users,dc=goauthentik,dc=io",
{
"userPassword": password,
"name": "user0_sn",
"uid": "user0_sn",
"objectClass": "person",
},
)
# User without SID
connection.strategy.add_entry(
"cn=user1,ou=users,dc=goauthentik,dc=io",
{
"userPassword": "test1111",
"name": "user1_sn",
"objectClass": "person",
},
)
# Duplicate users
connection.strategy.add_entry(
"cn=user2,ou=users,dc=goauthentik,dc=io",
{
"userPassword": "test2222",
"name": "user2_sn",
"uid": "unique-test2222",
"objectClass": "person",
},
)
connection.strategy.add_entry(
"cn=user3,ou=users,dc=goauthentik,dc=io",
{
"userPassword": "test2222",
"name": "user2_sn",
"uid": "unique-test2222",
"objectClass": "person",
},
)
# Group with posixGroup and memberUid
connection.strategy.add_entry(
"cn=group-posix,ou=groups,dc=goauthentik,dc=io",
{
"cn": "group-posix",
"objectClass": "posixGroup",
"memberUid": ["user-posix"],
},
)
# User with posixAccount
connection.strategy.add_entry(
"cn=user-posix,ou=users,dc=goauthentik,dc=io",
{
"userPassword": password,
"uid": "user-posix",
"cn": "user-posix",
"objectClass": "posixAccount",
},
)
# Locked out user
connection.strategy.add_entry(
"cn=user-nsaccountlock,ou=users,dc=goauthentik,dc=io",
{
"userPassword": password,
"uid": "user-nsaccountlock",
"cn": "user-nsaccountlock",
"objectClass": "person",
"nsaccountlock": ["TRUE"],
},
)
connection.bind()
return connection

View File

@ -4,7 +4,7 @@ from ldap3 import MOCK_SYNC, OFFLINE_SLAPD_2_4, Connection, Server
def mock_slapd_connection(password: str) -> Connection:
"""Create mock AD connection"""
"""Create mock SLAPD connection"""
server = Server("my_fake_server", get_info=OFFLINE_SLAPD_2_4)
_pass = "foo" # noqa # nosec
connection = Connection(

View File

@ -17,6 +17,7 @@ from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer
from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
from authentik.sources.ldap.tasks import ldap_sync, ldap_sync_all
from authentik.sources.ldap.tests.mock_ad import mock_ad_connection
from authentik.sources.ldap.tests.mock_freeipa import mock_freeipa_connection
from authentik.sources.ldap.tests.mock_slapd import mock_slapd_connection
LDAP_PASSWORD = generate_key()
@ -120,6 +121,24 @@ class LDAPSyncTests(TestCase):
self.assertTrue(User.objects.filter(username="user0_sn").exists())
self.assertFalse(User.objects.filter(username="user1_sn").exists())
def test_sync_users_freeipa_ish(self):
"""Test user sync (FreeIPA-ish), mainly testing vendor quirks"""
self.source.object_uniqueness_field = "uid"
self.source.property_mappings.set(
LDAPPropertyMapping.objects.filter(
Q(managed__startswith="goauthentik.io/sources/ldap/default")
| Q(managed__startswith="goauthentik.io/sources/ldap/openldap")
)
)
self.source.save()
connection = MagicMock(return_value=mock_freeipa_connection(LDAP_PASSWORD))
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
user_sync = UserLDAPSynchronizer(self.source)
user_sync.sync_full()
self.assertTrue(User.objects.filter(username="user0_sn").exists())
self.assertFalse(User.objects.filter(username="user1_sn").exists())
self.assertFalse(User.objects.get(username="user-nsaccountlock").is_active)
def test_sync_groups_ad(self):
"""Test group sync"""
self.source.property_mappings.set(

View File

@ -111,7 +111,7 @@ class PasswordStageView(ChallengeStageView):
current_stage: PasswordStage = self.executor.current_stage
if (
self.request.session[SESSION_KEY_INVALID_TRIES]
> current_stage.failed_attempts_before_cancel
>= current_stage.failed_attempts_before_cancel
):
self.logger.debug("User has exceeded maximum tries")
del self.request.session[SESSION_KEY_INVALID_TRIES]

View File

@ -108,7 +108,7 @@ class TestPasswordStage(FlowTestCase):
session[SESSION_KEY_PLAN] = plan
session.save()
for _ in range(self.stage.failed_attempts_before_cancel):
for _ in range(self.stage.failed_attempts_before_cancel - 1):
response = self.client.post(
reverse(
"authentik_api:flow-executor",
@ -118,6 +118,11 @@ class TestPasswordStage(FlowTestCase):
{"password": self.user.username + "test"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
flow=self.flow,
response_errors={"password": [{"string": "Invalid password", "code": "invalid"}]},
)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
@ -127,6 +132,7 @@ class TestPasswordStage(FlowTestCase):
self.assertEqual(response.status_code, 200)
# To ensure the plan has been cancelled, check SESSION_KEY_PLAN
self.assertNotIn(SESSION_KEY_PLAN, self.client.session)
self.assertStageResponse(response, flow=self.flow, error_message="Unknown error")
@patch(
"authentik.flows.views.executor.to_stage_response",

View File

@ -85,6 +85,19 @@ entries:
identifiers:
name: default-oobe-password-usable
model: authentik_policies_expression.expressionpolicy
- attrs:
expression: |
# This policy ensures that the setup flow can only be
# used one time
from authentik.flows.models import Flow, FlowAuthenticationRequirement
Flow.objects.filter(slug="initial-setup").update(
authentication=FlowAuthenticationRequirement.REQUIRE_SUPERUSER,
)
return True
id: policy-default-oobe-flow-set-authentication
identifiers:
name: default-oobe-flow-set-authentication
model: authentik_policies_expression.expressionpolicy
- attrs:
fields:
- !KeyOf prompt-field-header
@ -129,6 +142,7 @@ entries:
evaluate_on_plan: true
invalid_response_action: retry
re_evaluate_policies: false
id: binding-login
identifiers:
order: 100
stage: !KeyOf stage-default-authentication-login
@ -144,3 +158,8 @@ entries:
policy: !KeyOf policy-default-oobe-prefill-user
target: !KeyOf binding-password-write
model: authentik_policies.policybinding
- identifiers:
order: 0
policy: !KeyOf policy-default-oobe-flow-set-authentication
target: !KeyOf binding-login
model: authentik_policies.policybinding

View File

@ -42,9 +42,3 @@ entries:
user: !KeyOf admin-user
attrs:
key: !Context token
- model: authentik_blueprints.blueprintinstance
identifiers:
metadata:
labels:
blueprints.goauthentik.io/system-bootstrap: "true"
state: absent

View File

@ -32,7 +32,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.8.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.8.7}
restart: unless-stopped
command: server
environment:
@ -53,7 +53,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.8.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.8.7}
restart: unless-stopped
command: worker
environment:

View File

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

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-30 17:44+0000\n"
"POT-Creation-Date: 2023-09-02 15:45+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -325,6 +325,14 @@ msgstr ""
msgid "Certificate-Key Pairs"
msgstr ""
#: authentik/enterprise/models.py:193
msgid "License Usage"
msgstr ""
#: authentik/enterprise/models.py:194
msgid "License Usage Records"
msgstr ""
#: authentik/events/models.py:290
msgid "Event"
msgstr ""
@ -804,14 +812,22 @@ msgstr ""
msgid "Password Policies"
msgstr ""
#: authentik/policies/reputation/models.py:58
#: authentik/policies/reputation/models.py:67
msgid "Reputation Policy"
msgstr ""
#: authentik/policies/reputation/models.py:59
#: authentik/policies/reputation/models.py:68
msgid "Reputation Policies"
msgstr ""
#: authentik/policies/reputation/models.py:95
msgid "Reputation Score"
msgstr ""
#: authentik/policies/reputation/models.py:96
msgid "Reputation Scores"
msgstr ""
#: authentik/policies/templates/policies/denied.html:7
#: authentik/policies/templates/policies/denied.html:11
msgid "Permission denied"
@ -1242,11 +1258,11 @@ msgstr ""
msgid "Radius Providers"
msgstr ""
#: authentik/providers/saml/api/providers.py:260
#: authentik/providers/saml/api/providers.py:257
msgid "Invalid XML Syntax"
msgstr ""
#: authentik/providers/saml/api/providers.py:270
#: authentik/providers/saml/api/providers.py:267
#, python-format
msgid "Failed to import Metadata: %(message)s"
msgstr ""

Binary file not shown.

451
poetry.lock generated
View File

@ -163,13 +163,13 @@ files = [
[[package]]
name = "anyio"
version = "3.7.1"
version = "4.0.0"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
{file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
{file = "anyio-4.0.0-py3-none-any.whl", hash = "sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f"},
{file = "anyio-4.0.0.tar.gz", hash = "sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a"},
]
[package.dependencies]
@ -177,9 +177,9 @@ idna = ">=2.8"
sniffio = ">=1.1"
[package.extras]
doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"]
test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (<0.22)"]
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)"]
test = ["anyio[trio]", "coverage[toml] (>=7)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (>=0.22)"]
[[package]]
name = "argon2-cffi"
@ -280,13 +280,13 @@ wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}
[[package]]
name = "async-timeout"
version = "4.0.2"
version = "4.0.3"
description = "Timeout context manager for asyncio programs"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
files = [
{file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
{file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
]
[[package]]
@ -355,13 +355,13 @@ visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"]
[[package]]
name = "autopep8"
version = "2.0.2"
version = "2.0.4"
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
optional = false
python-versions = ">=3.6"
files = [
{file = "autopep8-2.0.2-py2.py3-none-any.whl", hash = "sha256:86e9303b5e5c8160872b2f5ef611161b2893e9bfe8ccc7e2f76385947d57a2f1"},
{file = "autopep8-2.0.2.tar.gz", hash = "sha256:f9849cdd62108cb739dbcdbfb7fdcc9a30d1b63c4cc3e1c1f893b5360941b61c"},
{file = "autopep8-2.0.4-py2.py3-none-any.whl", hash = "sha256:067959ca4a07b24dbd5345efa8325f5f58da4298dab0dde0443d5ed765de80cb"},
{file = "autopep8-2.0.4.tar.gz", hash = "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c"},
]
[package.dependencies]
@ -552,13 +552,13 @@ test = ["pytest", "pytest-cov"]
[[package]]
name = "celery"
version = "5.3.3"
version = "5.3.4"
description = "Distributed Task Queue."
optional = false
python-versions = ">=3.8"
files = [
{file = "celery-5.3.3-py3-none-any.whl", hash = "sha256:d65c0be70d0949fcda8893876a071a7cfd9f248f9ad92e1919845e5cbc268db7"},
{file = "celery-5.3.3.tar.gz", hash = "sha256:bac90ef99b70b9b5b5d4cfcebf6f1ab5168b86c6120bc7c5814cd8234dfd9381"},
{file = "celery-5.3.4-py3-none-any.whl", hash = "sha256:1e6ed40af72695464ce98ca2c201ad0ef8fd192246f6c9eac8bba343b980ad34"},
{file = "celery-5.3.4.tar.gz", hash = "sha256:9023df6a8962da79eb30c0c84d5f4863d9793a466354cc931d7f72423996de28"},
]
[package.dependencies]
@ -819,13 +819,13 @@ files = [
[[package]]
name = "click"
version = "8.1.6"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"},
{file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"},
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
@ -1125,13 +1125,13 @@ graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "django"
version = "4.2.4"
version = "4.2.5"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.8"
files = [
{file = "Django-4.2.4-py3-none-any.whl", hash = "sha256:860ae6a138a238fc4f22c99b52f3ead982bb4b1aad8c0122bcd8c8a3a02e409d"},
{file = "Django-4.2.4.tar.gz", hash = "sha256:7e4225ec065e0f354ccf7349a22d209de09cc1c074832be9eb84c51c1799c432"},
{file = "Django-4.2.5-py3-none-any.whl", hash = "sha256:b6b2b5cae821077f137dc4dade696a1c2aa292f892eca28fa8d7bfdf2608ddd4"},
{file = "Django-4.2.5.tar.gz", hash = "sha256:5e5c1c9548ffb7796b4a8a4782e9a2e5a3df3615259fc1bfd3ebc73b646146c1"},
]
[package.dependencies]
@ -1284,13 +1284,13 @@ djangorestframework = "*"
[[package]]
name = "dnspython"
version = "2.4.1"
version = "2.4.2"
description = "DNS toolkit"
optional = false
python-versions = ">=3.8,<4.0"
files = [
{file = "dnspython-2.4.1-py3-none-any.whl", hash = "sha256:5b7488477388b8c0b70a8ce93b227c5603bc7b77f1565afe8e729c36c51447d7"},
{file = "dnspython-2.4.1.tar.gz", hash = "sha256:c33971c79af5be968bb897e95c2448e11a645ee84d93b265ce0b7aabe5dfdca8"},
{file = "dnspython-2.4.2-py3-none-any.whl", hash = "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8"},
{file = "dnspython-2.4.2.tar.gz", hash = "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984"},
]
[package.extras]
@ -1414,13 +1414,13 @@ idna = ">=2.0.0"
[[package]]
name = "exceptiongroup"
version = "1.1.2"
version = "1.1.3"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
{file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
{file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"},
{file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"},
]
[package.extras]
@ -1560,13 +1560,13 @@ smmap = ">=3.0.1,<6"
[[package]]
name = "gitpython"
version = "3.1.32"
version = "3.1.34"
description = "GitPython is a Python library used to interact with Git repositories"
optional = false
python-versions = ">=3.7"
files = [
{file = "GitPython-3.1.32-py3-none-any.whl", hash = "sha256:e3d59b1c2c6ebb9dfa7a184daf3b6dd4914237e7488a1730a6d8f6f5d0b4187f"},
{file = "GitPython-3.1.32.tar.gz", hash = "sha256:8d9b8cb1e80b9735e8717c9362079d3ce4c6e5ddeebedd0361b228c3a67a62f6"},
{file = "GitPython-3.1.34-py3-none-any.whl", hash = "sha256:5d3802b98a3bae1c2b8ae0e1ff2e4aa16bcdf02c145da34d092324f599f01395"},
{file = "GitPython-3.1.34.tar.gz", hash = "sha256:85f7d365d1f6bf677ae51039c1ef67ca59091c7ebd5a3509aa399d4eda02d6dd"},
]
[package.dependencies]
@ -1687,13 +1687,13 @@ test = ["Cython (>=0.29.24,<0.30.0)"]
[[package]]
name = "humanize"
version = "4.7.0"
version = "4.8.0"
description = "Python humanize utilities"
optional = false
python-versions = ">=3.8"
files = [
{file = "humanize-4.7.0-py3-none-any.whl", hash = "sha256:df7c429c2d27372b249d3f26eb53b07b166b661326e0325793e0a988082e3889"},
{file = "humanize-4.7.0.tar.gz", hash = "sha256:7ca0e43e870981fa684acb5b062deb307218193bca1a01f2b2676479df849b3a"},
{file = "humanize-4.8.0-py3-none-any.whl", hash = "sha256:8bc9e2bb9315e61ec06bf690151ae35aeb65651ab091266941edf97c90836404"},
{file = "humanize-4.8.0.tar.gz", hash = "sha256:9783373bf1eec713a770ecaa7c2d7a7902c98398009dfa3d8a2df91eec9311e8"},
]
[package.extras]
@ -1841,13 +1841,13 @@ files = [
[[package]]
name = "jsonschema"
version = "4.18.4"
version = "4.19.0"
description = "An implementation of JSON Schema validation for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "jsonschema-4.18.4-py3-none-any.whl", hash = "sha256:971be834317c22daaa9132340a51c01b50910724082c2c1a2ac87eeec153a3fe"},
{file = "jsonschema-4.18.4.tar.gz", hash = "sha256:fb3642735399fa958c0d2aad7057901554596c63349f4f6b283c493cf692a25d"},
{file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"},
{file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"},
]
[package.dependencies]
@ -2520,13 +2520,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co
[[package]]
name = "pluggy"
version = "1.2.0"
version = "1.3.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"},
{file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"},
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
]
[package.extras]
@ -2840,13 +2840,13 @@ pydantic = [
[[package]]
name = "pygments"
version = "2.15.1"
version = "2.16.1"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.7"
files = [
{file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
{file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
{file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"},
{file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
]
[package.extras]
@ -2999,13 +2999,13 @@ files = [
[[package]]
name = "pytest"
version = "7.4.0"
version = "7.4.1"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"},
{file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"},
{file = "pytest-7.4.1-py3-none-any.whl", hash = "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"},
{file = "pytest-7.4.1.tar.gz", hash = "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab"},
]
[package.dependencies]
@ -3186,13 +3186,13 @@ files = [
[[package]]
name = "redis"
version = "4.6.0"
version = "5.0.0"
description = "Python client for Redis database and key-value store"
optional = false
python-versions = ">=3.7"
files = [
{file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"},
{file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"},
{file = "redis-5.0.0-py3-none-any.whl", hash = "sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0"},
{file = "redis-5.0.0.tar.gz", hash = "sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120"},
]
[package.dependencies]
@ -3204,13 +3204,13 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"
[[package]]
name = "referencing"
version = "0.30.0"
version = "0.30.2"
description = "JSON Referencing + Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "referencing-0.30.0-py3-none-any.whl", hash = "sha256:c257b08a399b6c2f5a3510a50d28ab5dbc7bbde049bcaf954d43c446f83ab548"},
{file = "referencing-0.30.0.tar.gz", hash = "sha256:47237742e990457f7512c7d27486394a9aadaf876cbfaa4be65b27b4f4d47c6b"},
{file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"},
{file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"},
]
[package.dependencies]
@ -3277,13 +3277,13 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
[[package]]
name = "rich"
version = "13.5.1"
version = "13.5.2"
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "rich-13.5.1-py3-none-any.whl", hash = "sha256:b97381b204a206e1be618f5e1215a57174a1a7732490b3bf6668cf41d30bc72d"},
{file = "rich-13.5.1.tar.gz", hash = "sha256:881653ee7037803559d8eae98f145e0a4c4b0ec3ff0300d2cc8d479c71fc6819"},
{file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"},
{file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"},
]
[package.dependencies]
@ -3295,108 +3295,108 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
[[package]]
name = "rpds-py"
version = "0.9.2"
version = "0.10.0"
description = "Python bindings to Rust's persistent data structures (rpds)"
optional = false
python-versions = ">=3.8"
files = [
{file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"},
{file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"},
{file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"},
{file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"},
{file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"},
{file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"},
{file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"},
{file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"},
{file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"},
{file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"},
{file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"},
{file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"},
{file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"},
{file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"},
{file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"},
{file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"},
{file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"},
{file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"},
{file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"},
{file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"},
{file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"},
{file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"},
{file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"},
{file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"},
{file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"},
{file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"},
{file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"},
{file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"},
{file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"},
{file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"},
{file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"},
{file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"},
{file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"},
{file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"},
{file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"},
{file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"},
{file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"},
{file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"},
{file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"},
{file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"},
{file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"},
{file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"},
{file = "rpds_py-0.10.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:c1e0e9916301e3b3d970814b1439ca59487f0616d30f36a44cead66ee1748c31"},
{file = "rpds_py-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ce8caa29ebbdcde67e5fd652c811d34bc01f249dbc0d61e5cc4db05ae79a83b"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad277f74b1c164f7248afa968700e410651eb858d7c160d109fb451dc45a2f09"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8e1c68303ccf7fceb50fbab79064a2636119fd9aca121f28453709283dbca727"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:780fcb855be29153901c67fc9c5633d48aebef21b90aa72812fa181d731c6b00"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bbd7b24d108509a1b9b6679fcc1166a7dd031dbef1f3c2c73788f42e3ebb3beb"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0700c2133ba203c4068aaecd6a59bda22e06a5e46255c9da23cbf68c6942215d"},
{file = "rpds_py-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:576da63eae7809f375932bfcbca2cf20620a1915bf2fedce4b9cc8491eceefe3"},
{file = "rpds_py-0.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23750a9b8a329844ba1fe267ca456bb3184984da2880ed17ae641c5af8de3fef"},
{file = "rpds_py-0.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d08395595c42bcd82c3608762ce734504c6d025eef1c06f42326a6023a584186"},
{file = "rpds_py-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1d7b7b71bcb82d8713c7c2e9c5f061415598af5938666beded20d81fa23e7640"},
{file = "rpds_py-0.10.0-cp310-none-win32.whl", hash = "sha256:97f5811df21703446b42303475b8b855ee07d6ab6cdf8565eff115540624f25d"},
{file = "rpds_py-0.10.0-cp310-none-win_amd64.whl", hash = "sha256:cdbed8f21204398f47de39b0a9b180d7e571f02dfb18bf5f1b618e238454b685"},
{file = "rpds_py-0.10.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:7a3a3d3e4f1e3cd2a67b93a0b6ed0f2499e33f47cc568e3a0023e405abdc0ff1"},
{file = "rpds_py-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc72ae476732cdb7b2c1acb5af23b478b8a0d4b6fcf19b90dd150291e0d5b26b"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0583f69522732bdd79dca4cd3873e63a29acf4a299769c7541f2ca1e4dd4bc6"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8b9a7cd381970e64849070aca7c32d53ab7d96c66db6c2ef7aa23c6e803f514"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d292cabd7c8335bdd3237ded442480a249dbcdb4ddfac5218799364a01a0f5c"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6903cdca64f1e301af9be424798328c1fe3b4b14aede35f04510989fc72f012"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bed57543c99249ab3a4586ddc8786529fbc33309e5e8a1351802a06ca2baf4c2"},
{file = "rpds_py-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15932ec5f224b0e35764dc156514533a4fca52dcfda0dfbe462a1a22b37efd59"},
{file = "rpds_py-0.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eb2d59bc196e6d3b1827c7db06c1a898bfa0787c0574af398e65ccf2e97c0fbe"},
{file = "rpds_py-0.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f99d74ddf9d3b6126b509e81865f89bd1283e3fc1b568b68cd7bd9dfa15583d7"},
{file = "rpds_py-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f70bec8a14a692be6dbe7ce8aab303e88df891cbd4a39af091f90b6702e28055"},
{file = "rpds_py-0.10.0-cp311-none-win32.whl", hash = "sha256:5f7487be65b9c2c510819e744e375bd41b929a97e5915c4852a82fbb085df62c"},
{file = "rpds_py-0.10.0-cp311-none-win_amd64.whl", hash = "sha256:748e472345c3a82cfb462d0dff998a7bf43e621eed73374cb19f307e97e08a83"},
{file = "rpds_py-0.10.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:d4639111e73997567343df6551da9dd90d66aece1b9fc26c786d328439488103"},
{file = "rpds_py-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f4760e1b02173f4155203054f77a5dc0b4078de7645c922b208d28e7eb99f3e2"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a6420a36975e0073acaeee44ead260c1f6ea56812cfc6c31ec00c1c48197173"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:58fc4d66ee349a23dbf08c7e964120dc9027059566e29cf0ce6205d590ed7eca"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:063411228b852fb2ed7485cf91f8e7d30893e69b0acb207ec349db04cccc8225"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65af12f70355de29e1092f319f85a3467f4005e959ab65129cb697169ce94b86"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298e8b5d8087e0330aac211c85428c8761230ef46a1f2c516d6a2f67fb8803c5"},
{file = "rpds_py-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5b9bf77008f2c55dabbd099fd3ac87009471d223a1c7ebea36873d39511b780a"},
{file = "rpds_py-0.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c7853f27195598e550fe089f78f0732c66ee1d1f0eaae8ad081589a5a2f5d4af"},
{file = "rpds_py-0.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:75dbfd41a61bc1fb0536bf7b1abf272dc115c53d4d77db770cd65d46d4520882"},
{file = "rpds_py-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b25136212a3d064a8f0b9ebbb6c57094c5229e0de76d15c79b76feff26aeb7b8"},
{file = "rpds_py-0.10.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:9affee8cb1ec453382c27eb9043378ab32f49cd4bc24a24275f5c39bf186c279"},
{file = "rpds_py-0.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4d55528ef13af4b4e074d067977b1f61408602f53ae4537dccf42ba665c2c7bd"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7865df1fb564092bcf46dac61b5def25342faf6352e4bc0e61a286e3fa26a3d"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f5cc8c7bc99d2bbcd704cef165ca7d155cd6464c86cbda8339026a42d219397"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbae50d352e4717ffc22c566afc2d0da744380e87ed44a144508e3fb9114a3f4"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fccbf0cd3411719e4c9426755df90bf3449d9fc5a89f077f4a7f1abd4f70c910"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d10c431073dc6ebceed35ab22948a016cc2b5120963c13a41e38bdde4a7212"},
{file = "rpds_py-0.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b401e8b9aece651512e62c431181e6e83048a651698a727ea0eb0699e9f9b74"},
{file = "rpds_py-0.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:7618a082c55cf038eede4a918c1001cc8a4411dfe508dc762659bcd48d8f4c6e"},
{file = "rpds_py-0.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:b3226b246facae14909b465061ddcfa2dfeadb6a64f407f24300d42d69bcb1a1"},
{file = "rpds_py-0.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a8edd467551c1102dc0f5754ab55cd0703431cd3044edf8c8e7d9208d63fa453"},
{file = "rpds_py-0.10.0-cp38-none-win32.whl", hash = "sha256:71333c22f7cf5f0480b59a0aef21f652cf9bbaa9679ad261b405b65a57511d1e"},
{file = "rpds_py-0.10.0-cp38-none-win_amd64.whl", hash = "sha256:a8ab1adf04ae2d6d65835995218fd3f3eb644fe20655ca8ee233e2c7270ff53b"},
{file = "rpds_py-0.10.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:87c93b25d538c433fb053da6228c6290117ba53ff6a537c133b0f2087948a582"},
{file = "rpds_py-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7996aed3f65667c6dcc8302a69368435a87c2364079a066750a2eac75ea01e"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8856aa76839dc234d3469f1e270918ce6bec1d6a601eba928f45d68a15f04fc3"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00215f6a9058fbf84f9d47536902558eb61f180a6b2a0fa35338d06ceb9a2e5a"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23a059143c1393015c68936370cce11690f7294731904bdae47cc3e16d0b2474"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e5c26905aa651cc8c0ddc45e0e5dea2a1296f70bdc96af17aee9d0493280a17"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c651847545422c8131660704c58606d841e228ed576c8f1666d98b3d318f89da"},
{file = "rpds_py-0.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80992eb20755701753e30a6952a96aa58f353d12a65ad3c9d48a8da5ec4690cf"},
{file = "rpds_py-0.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ffcf18ad3edf1c170e27e88b10282a2c449aa0358659592462448d71b2000cfc"},
{file = "rpds_py-0.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:08e08ccf5b10badb7d0a5c84829b914c6e1e1f3a716fdb2bf294e2bd01562775"},
{file = "rpds_py-0.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7150b83b3e3ddaac81a8bb6a9b5f93117674a0e7a2b5a5b32ab31fdfea6df27f"},
{file = "rpds_py-0.10.0-cp39-none-win32.whl", hash = "sha256:3455ecc46ea443b5f7d9c2f946ce4017745e017b0d0f8b99c92564eff97e97f5"},
{file = "rpds_py-0.10.0-cp39-none-win_amd64.whl", hash = "sha256:afe6b5a04b2ab1aa89bad32ca47bf71358e7302a06fdfdad857389dca8fb5f04"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:b1cb078f54af0abd835ca76f93a3152565b73be0f056264da45117d0adf5e99c"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8e7e2b3577e97fa43c2c2b12a16139b2cedbd0770235d5179c0412b4794efd9b"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae46a50d235f1631d9ec4670503f7b30405103034830bc13df29fd947207f795"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f869e34d2326e417baee430ae998e91412cc8e7fdd83d979277a90a0e79a5b47"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d544a614055b131111bed6edfa1cb0fb082a7265761bcb03321f2dd7b5c6c48"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee9c2f6ca9774c2c24bbf7b23086264e6b5fa178201450535ec0859739e6f78d"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2da4a8c6d465fde36cea7d54bf47b5cf089073452f0e47c8632ecb9dec23c07"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac00c41dd315d147b129976204839ca9de699d83519ff1272afbe4fb9d362d12"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0155c33af0676fc38e1107679be882077680ad1abb6303956b97259c3177e85e"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:db6585b600b2e76e98131e0ac0e5195759082b51687ad0c94505970c90718f4a"},
{file = "rpds_py-0.10.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:7b6975d3763d0952c111700c0634968419268e6bbc0b55fe71138987fa66f309"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:6388e4e95a26717b94a05ced084e19da4d92aca883f392dffcf8e48c8e221a24"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:18f87baa20e02e9277ad8960cd89b63c79c05caf106f4c959a9595c43f2a34a5"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f05fc7d832e970047662b3440b190d24ea04f8d3c760e33e7163b67308c878"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:291c9ce3929a75b45ce8ddde2aa7694fc8449f2bc8f5bd93adf021efaae2d10b"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:861d25ae0985a1dd5297fee35f476b60c6029e2e6e19847d5b4d0a43a390b696"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:668d2b45d62c68c7a370ac3dce108ffda482b0a0f50abd8b4c604a813a59e08f"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344b89384c250ba6a4ce1786e04d01500e4dac0f4137ceebcaad12973c0ac0b3"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:885e023e73ce09b11b89ab91fc60f35d80878d2c19d6213a32b42ff36543c291"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:841128a22e6ac04070a0f84776d07e9c38c4dcce8e28792a95e45fc621605517"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:899b5e7e2d5a8bc92aa533c2d4e55e5ebba095c485568a5e4bedbc163421259a"},
{file = "rpds_py-0.10.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e7947d9a6264c727a556541b1630296bbd5d0a05068d21c38dde8e7a1c703ef0"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4992266817169997854f81df7f6db7bdcda1609972d8ffd6919252f09ec3c0f6"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:26d9fd624649a10e4610fab2bc820e215a184d193e47d0be7fe53c1c8f67f370"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0028eb0967942d0d2891eae700ae1a27b7fd18604cfcb16a1ef486a790fee99e"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9e7e493ded7042712a374471203dd43ae3fff5b81e3de1a0513fa241af9fd41"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d68a8e8a3a816629283faf82358d8c93fe5bd974dd2704152394a3de4cec22a"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6d5f061f6a2aa55790b9e64a23dfd87b6664ab56e24cd06c78eb43986cb260b"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c7c4266c1b61eb429e8aeb7d8ed6a3bfe6c890a1788b18dbec090c35c6b93fa"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80772e3bda6787510d9620bc0c7572be404a922f8ccdfd436bf6c3778119464c"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b98e75b21fc2ba5285aef8efaf34131d16af1c38df36bdca2f50634bea2d3060"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:d63787f289944cc4bde518ad2b5e70a4f0d6e2ce76324635359c74c113fd188f"},
{file = "rpds_py-0.10.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:872f3dcaa8bf2245944861d7311179d2c0c9b2aaa7d3b464d99a7c2e401f01fa"},
{file = "rpds_py-0.10.0.tar.gz", hash = "sha256:e36d7369363d2707d5f68950a64c4e025991eb0177db01ccb6aa6facae48b69f"},
]
[[package]]
@ -3415,28 +3415,28 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.0.286"
version = "0.0.287"
description = "An extremely fast Python linter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.0.286-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:8e22cb557e7395893490e7f9cfea1073d19a5b1dd337f44fd81359b2767da4e9"},
{file = "ruff-0.0.286-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:68ed8c99c883ae79a9133cb1a86d7130feee0397fdf5ba385abf2d53e178d3fa"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8301f0bb4ec1a5b29cfaf15b83565136c47abefb771603241af9d6038f8981e8"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acc4598f810bbc465ce0ed84417ac687e392c993a84c7eaf3abf97638701c1ec"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88c8e358b445eb66d47164fa38541cfcc267847d1e7a92dd186dddb1a0a9a17f"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0433683d0c5dbcf6162a4beb2356e820a593243f1fa714072fec15e2e4f4c939"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddb61a0c4454cbe4623f4a07fef03c5ae921fe04fede8d15c6e36703c0a73b07"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:47549c7c0be24c8ae9f2bce6f1c49fbafea83bca80142d118306f08ec7414041"},
{file = "ruff-0.0.286-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:559aa793149ac23dc4310f94f2c83209eedb16908a0343663be19bec42233d25"},
{file = "ruff-0.0.286-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d73cfb1c3352e7aa0ce6fb2321f36fa1d4a2c48d2ceac694cb03611ddf0e4db6"},
{file = "ruff-0.0.286-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:3dad93b1f973c6d1db4b6a5da8690c5625a3fa32bdf38e543a6936e634b83dc3"},
{file = "ruff-0.0.286-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26afc0851f4fc3738afcf30f5f8b8612a31ac3455cb76e611deea80f5c0bf3ce"},
{file = "ruff-0.0.286-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9b6b116d1c4000de1b9bf027131dbc3b8a70507788f794c6b09509d28952c512"},
{file = "ruff-0.0.286-py3-none-win32.whl", hash = "sha256:556e965ac07c1e8c1c2d759ac512e526ecff62c00fde1a046acb088d3cbc1a6c"},
{file = "ruff-0.0.286-py3-none-win_amd64.whl", hash = "sha256:5d295c758961376c84aaa92d16e643d110be32add7465e197bfdaec5a431a107"},
{file = "ruff-0.0.286-py3-none-win_arm64.whl", hash = "sha256:1d6142d53ab7f164204b3133d053c4958d4d11ec3a39abf23a40b13b0784e3f0"},
{file = "ruff-0.0.286.tar.gz", hash = "sha256:f1e9d169cce81a384a26ee5bb8c919fe9ae88255f39a1a69fd1ebab233a85ed2"},
{file = "ruff-0.0.287-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:1e0f9ee4c3191444eefeda97d7084721d9b8e29017f67997a20c153457f2eafd"},
{file = "ruff-0.0.287-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:e9843e5704d4fb44e1a8161b0d31c1a38819723f0942639dfeb53d553be9bfb5"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca1ed11d759a29695aed2bfc7f914b39bcadfe2ef08d98ff69c873f639ad3a8"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1cf4d5ad3073af10f186ea22ce24bc5a8afa46151f6896f35c586e40148ba20b"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d9d58bcb29afd72d2afe67120afcc7d240efc69a235853813ad556443dc922"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:06ac5df7dd3ba8bf83bba1490a72f97f1b9b21c7cbcba8406a09de1a83f36083"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2bfb478e1146a60aa740ab9ebe448b1f9e3c0dfb54be3cc58713310eef059c30"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00d579a011949108c4b4fa04c4f1ee066dab536a9ba94114e8e580c96be2aeb4"},
{file = "ruff-0.0.287-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a810a79b8029cc92d06c36ea1f10be5298d2323d9024e1d21aedbf0a1a13e5"},
{file = "ruff-0.0.287-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:150007028ad4976ce9a7704f635ead6d0e767f73354ce0137e3e44f3a6c0963b"},
{file = "ruff-0.0.287-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a24a280db71b0fa2e0de0312b4aecb8e6d08081d1b0b3c641846a9af8e35b4a7"},
{file = "ruff-0.0.287-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2918cb7885fa1611d542de1530bea3fbd63762da793751cc8c8d6e4ba234c3d8"},
{file = "ruff-0.0.287-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:33d7b251afb60bec02a64572b0fd56594b1923ee77585bee1e7e1daf675e7ae7"},
{file = "ruff-0.0.287-py3-none-win32.whl", hash = "sha256:022f8bed2dcb5e5429339b7c326155e968a06c42825912481e10be15dafb424b"},
{file = "ruff-0.0.287-py3-none-win_amd64.whl", hash = "sha256:26bd0041d135a883bd6ab3e0b29c42470781fb504cf514e4c17e970e33411d90"},
{file = "ruff-0.0.287-py3-none-win_arm64.whl", hash = "sha256:44bceb3310ac04f0e59d4851e6227f7b1404f753997c7859192e41dbee9f5c8d"},
{file = "ruff-0.0.287.tar.gz", hash = "sha256:02dc4f5bf53ef136e459d467f3ce3e04844d509bc46c025a05b018feb37bbc39"},
]
[[package]]
@ -3525,18 +3525,18 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"]
[[package]]
name = "setuptools"
version = "68.0.0"
version = "68.1.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"},
{file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"},
{file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"},
{file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "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,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
@ -3772,27 +3772,30 @@ windows-platform = ["pywin32 (!=226)", "pywin32 (!=226)", "twisted[all-non-platf
[[package]]
name = "twisted-iocpsupport"
version = "1.0.3"
version = "1.0.4"
description = "An extension for use in the twisted I/O Completion Ports reactor."
optional = false
python-versions = "*"
files = [
{file = "twisted-iocpsupport-1.0.3.tar.gz", hash = "sha256:afb00801fdfbaccf0d0173a722626500023d4a19719ac9f129d1347a32e2fc66"},
{file = "twisted_iocpsupport-1.0.3-cp310-cp310-win32.whl", hash = "sha256:a379ef56a576c8090889f74441bc3822ca31ac82253cc61e8d50631bcb0c26d0"},
{file = "twisted_iocpsupport-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1ea2c3fbdb739c95cc8b3355305cd593d2c9ec56d709207aa1a05d4d98671e85"},
{file = "twisted_iocpsupport-1.0.3-cp311-cp311-win32.whl", hash = "sha256:7efcdfafb377f32db90f42bd5fc5bb32cd1e3637ee936cdaf3aff4f4786ab3bf"},
{file = "twisted_iocpsupport-1.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1dbfac706972bf9ec5ce1ddbc735d2ebba406ad363345df8751ffd5252aa1618"},
{file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:1ddfc5fa22ec6f913464b736b3f46e642237f17ac41be47eed6fa9bd52f5d0e0"},
{file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:1bdccbb22199fc69fd7744d6d2dfd22d073c028c8611d994b41d2d2ad0e0f40d"},
{file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:db11c80054b52dbdea44d63d5474a44c9a6531882f0e2960268b15123088641a"},
{file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:67bec1716eb8f466ef366bbf262e1467ecc9e20940111207663ac24049785bad"},
{file = "twisted_iocpsupport-1.0.3-cp38-cp38-win32.whl", hash = "sha256:98a6f16ab215f8c1446e9fc60aaed0ab7c746d566aa2f3492a23cea334e6bebb"},
{file = "twisted_iocpsupport-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:4f249d0baac836bb431d6fa0178be063a310136bc489465a831e3abd2d7acafd"},
{file = "twisted_iocpsupport-1.0.3-cp39-cp39-win32.whl", hash = "sha256:aaca8f30c3b7c80d27a33fe9fe0d0bac42b1b012ddc60f677175c30e1becc1f3"},
{file = "twisted_iocpsupport-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:dff43136c33665c2d117a73706aef6f7d6433e5c4560332a118fe066b16b8695"},
{file = "twisted_iocpsupport-1.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8faceae553cfadc42ad791b1790e7cdecb7751102608c405217f6a26e877e0c5"},
{file = "twisted_iocpsupport-1.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6f8c433faaad5d53d30d1da6968d5a3730df415e2efb6864847267a9b51290cd"},
{file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"},
{file = "twisted-iocpsupport-1.0.4.tar.gz", hash = "sha256:858096c0d15e33f15ac157f455d8f86f2f2cdd223963e58c0f682a3af8362d89"},
{file = "twisted_iocpsupport-1.0.4-cp310-cp310-win32.whl", hash = "sha256:afa2b630797f9ed2f27f3d9f55e3f72b4244911e45a8c82756f44babbf0b243e"},
{file = "twisted_iocpsupport-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:0058c963c8957bcd3deda62122e89953c9de1e867a274facc9b15dde1a9f31e8"},
{file = "twisted_iocpsupport-1.0.4-cp311-cp311-win32.whl", hash = "sha256:196f7c7ccad4ba4d1783b1c4e1d1b22d93c04275cd780bf7498d16c77319ad6e"},
{file = "twisted_iocpsupport-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:4e5f97bcbabdd79cbaa969b63439b89801ea560f11d42b0a387634275c633623"},
{file = "twisted_iocpsupport-1.0.4-cp312-cp312-win32.whl", hash = "sha256:6081bd7c2f4fcf9b383dcdb3b3385d75a26a7c9d2be25b6950c3d8ea652d2d2d"},
{file = "twisted_iocpsupport-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:76f7e67cec1f1d097d1f4ed7de41be3d74546e1a4ede0c7d56e775c4dce5dfb0"},
{file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:3d306fc4d88a6bcf61ce9d572c738b918578121bfd72891625fab314549024b5"},
{file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:391ac4d6002a80e15f35adc4ad6056f4fe1c17ceb0d1f98ba01b0f4f917adfd7"},
{file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:0c1b5cf37f0b2d96cc3c9bc86fff16613b9f5d0ca565c96cf1f1fb8cfca4b81c"},
{file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:3c5dc11d72519e55f727320e3cee535feedfaee09c0f0765ed1ca7badff1ab3c"},
{file = "twisted_iocpsupport-1.0.4-cp38-cp38-win32.whl", hash = "sha256:cc86c2ef598c15d824a243c2541c29459881c67fc3c0adb6efe2242f8f0ec3af"},
{file = "twisted_iocpsupport-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c27985e949b9b1a1fb4c20c71d315c10ea0f93fdf3ccdd4a8c158b5926edd8c8"},
{file = "twisted_iocpsupport-1.0.4-cp39-cp39-win32.whl", hash = "sha256:e311dfcb470696e3c077249615893cada598e62fa7c4e4ca090167bd2b7d331f"},
{file = "twisted_iocpsupport-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4574eef1f3bb81501fb02f911298af3c02fe8179c31a33b361dd49180c3e644d"},
{file = "twisted_iocpsupport-1.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:872747a3b64e2909aee59c803ccd0bceb9b75bf27915520ebd32d69687040fa2"},
{file = "twisted_iocpsupport-1.0.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:c2712b778bacf1db434e3e065adfed3db300754186a29aecac1efae9ef4bcaff"},
{file = "twisted_iocpsupport-1.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7c66fa0aa4236b27b3c61cb488662d85dae746a6d1c7b0d91cf7aae118445adf"},
{file = "twisted_iocpsupport-1.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:300437af17396a945a58dcfffd77863303a8b6d9e65c6e81f1d2eed55b50d444"},
]
[[package]]
@ -4012,33 +4015,33 @@ watchmedo = ["PyYAML (>=3.10)"]
[[package]]
name = "watchfiles"
version = "0.19.0"
version = "0.20.0"
description = "Simple, modern and high performance file watching and code reload in python."
optional = false
python-versions = ">=3.7"
files = [
{file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"},
{file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"},
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"},
{file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"},
{file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"},
{file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"},
{file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"},
{file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"},
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"},
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"},
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"},
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"},
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"},
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"},
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"},
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"},
{file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"},
{file = "watchfiles-0.20.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3796312bd3587e14926013612b23066912cf45a14af71cf2b20db1c12dadf4e9"},
{file = "watchfiles-0.20.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d0002d81c89a662b595645fb684a371b98ff90a9c7d8f8630c82f0fde8310458"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:570848706440373b4cd8017f3e850ae17f76dbdf1e9045fc79023b11e1afe490"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0351d20d03c6f7ad6b2e8a226a5efafb924c7755ee1e34f04c77c3682417fa"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:007dcc4a401093010b389c044e81172c8a2520dba257c88f8828b3d460c6bb38"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d82dbc1832da83e441d112069833eedd4cf583d983fb8dd666fbefbea9d99c0"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99f4c65fd2fce61a571b2a6fcf747d6868db0bef8a934e8ca235cc8533944d95"},
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5392dd327a05f538c56edb1c6ebba6af91afc81b40822452342f6da54907bbdf"},
{file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:08dc702529bb06a2b23859110c214db245455532da5eaea602921687cfcd23db"},
{file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d4e66a857621584869cfbad87039e65dadd7119f0d9bb9dbc957e089e32c164"},
{file = "watchfiles-0.20.0-cp37-abi3-win32.whl", hash = "sha256:a03d1e6feb7966b417f43c3e3783188167fd69c2063e86bad31e62c4ea794cc5"},
{file = "watchfiles-0.20.0-cp37-abi3-win_amd64.whl", hash = "sha256:eccc8942bcdc7d638a01435d915b913255bbd66f018f1af051cd8afddb339ea3"},
{file = "watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c"},
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d97db179f7566dcf145c5179ddb2ae2a4450e3a634eb864b09ea04e68c252e8e"},
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:835df2da7a5df5464c4a23b2d963e1a9d35afa422c83bf4ff4380b3114603644"},
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:608cd94a8767f49521901aff9ae0c92cc8f5a24d528db7d6b0295290f9d41193"},
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89d1de8218874925bce7bb2ae9657efc504411528930d7a83f98b1749864f2ef"},
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:13f995d5152a8ba4ed7c2bbbaeee4e11a5944defc7cacd0ccb4dcbdcfd78029a"},
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9b5c8d3be7b502f8c43a33c63166ada8828dbb0c6d49c8f9ce990a96de2f5a49"},
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e43af4464daa08723c04b43cf978ab86cc55c684c16172622bdac64b34e36af0"},
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d9e1f75c4f86c93d73b5bd1ebe667558357548f11b4f8af4e0e272f79413ce"},
{file = "watchfiles-0.20.0.tar.gz", hash = "sha256:728575b6b94c90dd531514677201e8851708e6e4b5fe7028ac506a200b622019"},
]
[package.dependencies]
@ -4075,17 +4078,17 @@ pyOpenSSL = ">=23.2.0"
[[package]]
name = "websocket-client"
version = "1.6.1"
version = "1.6.2"
description = "WebSocket client for Python with low level API options"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"},
{file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"},
{file = "websocket-client-1.6.2.tar.gz", hash = "sha256:53e95c826bf800c4c465f50093a8c4ff091c7327023b10bfaff40cf1ef170eaa"},
{file = "websocket_client-1.6.2-py3-none-any.whl", hash = "sha256:ce54f419dfae71f4bdba69ebe65bf7f0a93fe71bc009ad3a010aacc3eebad537"},
]
[package.extras]
docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"]
docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"]
optional = ["python-socks", "wsaccel"]
test = ["websockets"]

View File

@ -1,5 +1,5 @@
# Stage 1: Build website
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:20.5 as web-builder
COPY ./web /static/

View File

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

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2023.8.2
version: 2023.8.7
description: Making authentication simple.
contact:
email: hello@goauthentik.io

View File

@ -263,7 +263,7 @@ export class AdminInterface extends Interface {
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Flows & Stages")}</span>
<span slot="label">${msg("Flows and Stages")}</span>
<ak-sidebar-item
path="/flow/flows"
.activeWhen=${[`^/flow/flows/(?<slug>${SLUG_REGEX})$`]}
@ -295,10 +295,10 @@ export class AdminInterface extends Interface {
path="/core/sources"
.activeWhen=${[`^/core/sources/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${msg("Federation & Social login")}</span>
<span slot="label">${msg("Federation and Social login")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/tokens">
<span slot="label">${msg("Tokens & App passwords")}</span>
<span slot="label">${msg("Tokens and App passwords")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages/invitations">
<span slot="label">${msg("Invitations")}</span>

View File

@ -87,7 +87,7 @@ export class ApplicationViewPage extends AKElement {
.iconImage=${true}
>
<ak-app-icon
size=${PFSize.Small}
size=${PFSize.Medium}
slot="icon"
.app=${this.application}
></ak-app-icon>

View File

@ -69,7 +69,7 @@ export class AkCryptoCertificateSearch extends CustomListenerElement(AKElement)
}
get value() {
return this.selectedKeypair ? renderValue(this.selectedKeypair) : undefined;
return this.selectedKeypair ? renderValue(this.selectedKeypair) : null;
}
connectedCallback() {

View File

@ -66,7 +66,7 @@ export class FlowSearch<T extends Flow> extends CustomListenerElement(AKElement)
selectedFlow?: T;
get value() {
return this.selectedFlow ? getFlowValue(this.selectedFlow) : undefined;
return this.selectedFlow ? getFlowValue(this.selectedFlow) : null;
}
constructor() {

View File

@ -142,7 +142,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
renderToolbar(): TemplateResult {
return html`
<ak-stage-wizard
createText=${msg("Create & bind Stage")}
createText=${msg("Create and bind Stage")}
?showBindingPage=${true}
bindingTarget=${ifDefined(this.target)}
></ak-stage-wizard>

View File

@ -194,7 +194,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
renderToolbar(): TemplateResult {
return html`<ak-policy-wizard
createText=${msg("Create & bind Policy")}
createText=${msg("Create and bind Policy")}
?showBindingPage=${true}
bindingTarget=${ifDefined(this.target)}
></ak-policy-wizard>

View File

@ -93,7 +93,7 @@ doesn't pass when either or both of the selected options are equal or above the
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.checkIp, false)}
?checked=${first(this.instance?.checkIp, true)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">

View File

@ -205,8 +205,8 @@ ${this.instance?.redirectUris}</textarea
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Signing Key")} name="signingKey">
<ak-crypto-certificate-search
certificate=${this.instance?.signingKey}
singleton
certificate=${ifDefined(this.instance?.signingKey || "")}
?singleton=${!this.instance}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">${msg("Key used to sign the tokens.")}</p>
</ak-form-element-horizontal>

View File

@ -24,7 +24,7 @@ import { Source, SourcesApi } from "@goauthentik/api";
@customElement("ak-source-list")
export class SourceListPage extends TablePage<Source> {
pageTitle(): string {
return msg("Federation & Social login");
return msg("Federation and Social login");
}
pageDescription(): string | undefined {
return msg(

View File

@ -14,18 +14,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { Source, SourcesApi } from "@goauthentik/api";
export function renderSourceIcon(name: string, iconUrl: string | undefined | null): TemplateResult {
const icon = html`<i class="fas fa-share-square" title="${name}"></i>`;
if (iconUrl) {
if (iconUrl.startsWith("fa://")) {
const url = iconUrl.replaceAll("fa://", "");
return html`<i class="fas ${url}" title="${name}"></i>`;
}
return html`<img src="${iconUrl}" alt="${name}" />`;
}
return icon;
}
@customElement("ak-source-view")
export class SourceViewPage extends AKElement {
@property({ type: String })

View File

@ -0,0 +1,13 @@
import { TemplateResult, html } from "lit";
export function renderSourceIcon(name: string, iconUrl: string | undefined | null): TemplateResult {
const icon = html`<i class="fas fa-share-square" title="${name}"></i>`;
if (iconUrl) {
if (iconUrl.startsWith("fa://")) {
const url = iconUrl.replaceAll("fa://", "");
return html`<i class="fas ${url}" title="${name}"></i>`;
}
return html`<img src="${iconUrl}" alt="${name}" />`;
}
return icon;
}

View File

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

View File

@ -1,4 +1,4 @@
import { renderSourceIcon } from "@goauthentik/admin/sources/SourceViewPage";
import { renderSourceIcon } from "@goauthentik/app/admin/sources/utils";
import "@goauthentik/elements/Divider";
import "@goauthentik/elements/EmptyState";
import "@goauthentik/elements/forms/FormElement";

View File

@ -1,4 +1,4 @@
import { renderSourceIcon } from "@goauthentik/admin/sources/SourceViewPage";
import { renderSourceIcon } from "@goauthentik/app/admin/sources/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { me } from "@goauthentik/common/users";

View File

@ -2292,9 +2292,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>Aktuell sind keine Richtlinien mit diesem Objekt verknüpft.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2697,10 +2694,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>Neue Quelle erstellen.</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Föderierter &amp; Social Login</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Identitätsquellen, die entweder mit der Datenbank von authentik synchronisiert oder von Benutzern verwendet werden können, um sich selbst zu authentifizieren und zu registrieren.</target>
@ -4644,9 +4637,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Phasen-Verknüpfung</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5214,18 +5204,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Anpassung</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Abläufe &amp; Phasen</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Verzeichnis</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Tokens &amp; App Passwörter</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>System</target>
@ -5893,6 +5875,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2438,10 +2438,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>No policies are currently bound to this object.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
<target>Create &amp; bind Policy</target>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
<target>Bind existing policy</target>
@ -2858,10 +2854,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>Create a new source.</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Federation &amp; Social login</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</target>
@ -4912,10 +4904,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Bind stage</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
<target>Create &amp; bind Stage</target>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
<target>Bind existing stage</target>
@ -5512,18 +5500,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Customisation</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Flows &amp; Stages</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Directory</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Tokens &amp; App passwords</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>System</target>
@ -6209,6 +6189,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2250,9 +2250,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>Actualmente, no hay políticas vinculadas a este objeto.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2649,10 +2646,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s19b09f4fc72175d1">
<source>Create a new source.</source>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Inicio de sesión de federación y redes</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Fuentes de identidades, que se pueden sincronizar en la base de datos de authentik o que los usuarios pueden utilizar para autenticarse e inscribirse ellos mismos.</target>
@ -4565,9 +4558,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Etapa Bind</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5131,18 +5121,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Personalización</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Flujos y etapas</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Directorio</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Tokens y contraseñas de aplicaciones</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>Sistema</target>
@ -5801,6 +5783,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2308,10 +2308,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>Aucune politique n'est actuellement lié à cet objet.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
<target>Créer &amp; Lier une politique</target>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
<target>Lier une politique existante</target>
@ -2716,10 +2712,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>Créer une nouvelle source.</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Fédération &amp; Connection Sociale</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Sources d'identités, qui peuvent soit être synchronisées dans la base de données d'authentik, soit être utilisées par les utilisateurs pour s'authentifier et s'inscrire.</target>
@ -4655,10 +4647,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Lier une étape</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
<target>Créer &amp; Lier une étape</target>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
<target>Lier une étape existante</target>
@ -5228,18 +5216,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Personalisation</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Flux &amp; Étapes</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Répertoire</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Jetons &amp; mots de passe d'application</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>Système</target>
@ -5908,6 +5888,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2353,9 +2353,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>Żadne zasady nie są obecnie powiązane z tym obiektem.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2764,10 +2761,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>Utwórz nowe źródło.</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Logowanie federacyjne i społecznościowe</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Źródła tożsamości, które mogą być zsynchronizowane z bazą danych authentik lub mogą być używane przez użytkowników do uwierzytelniania i rejestracji.</target>
@ -4764,9 +4757,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Powiąż etap</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5352,18 +5342,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Dostosowywanie</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Przepływy i etapy</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Katalog</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Tokeny i hasła aplikacji</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>System</target>
@ -6040,6 +6022,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2412,10 +2412,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="sc15d60377cc8aaac">
<source>No policies are currently bound to this object.</source>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
@ -2832,10 +2828,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s19b09f4fc72175d1">
<source>Create a new source.</source>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
@ -4871,10 +4863,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s207e8b106806d7e4">
<source>Bind stage</source>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
@ -5463,18 +5451,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s1823625e6f831d73">
<source>Customisation</source>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
@ -6144,6 +6124,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2249,9 +2249,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>Hiçbir ilke şu anda bu nesneye bağlı değildir.</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2648,10 +2645,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s19b09f4fc72175d1">
<source>Create a new source.</source>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>Federasyon ve Sosyal Giriş</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Auentik'in veritabanına senkronize edilebilen ya da kullanıcılar tarafından kimlik doğrulaması ve kayıt yaptırmak için kullanılabilen kimliklerin kaynakları.</target>
@ -4556,9 +4549,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Bağlama aşaması</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5121,18 +5111,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>Özelleştirme</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>Akışlar ve Aşamalar</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Rehber</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>Belirteçler ve Uygulama parolaları</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>Sistem</target>
@ -5791,6 +5773,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -618,9 +618,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>未找到 URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot;。</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>未找到 URL "
<x id="0" equiv-text="${this.url}"/>"。</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1072,8 +1072,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 &quot;.*&quot;。请注意这可能带来的安全影响。</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1819,8 +1819,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 &quot;fa-test&quot;。</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -3041,11 +3041,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>当前没有策略绑定到此对象。</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
<target>创建 &amp; 绑定策略</target>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
@ -3248,8 +3243,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 &quot;memberUid&quot; 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3566,11 +3561,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>创建一个新身份来源。</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>联结与社交登录</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
@ -4046,8 +4036,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 &quot;minutes=5&quot;。</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -4056,8 +4046,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>格式:&quot;weeks=3;days=2;hours=3,seconds=2&quot;。</target>
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>格式:"weeks=3;days=2;hours=3,seconds=2"。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
@ -4253,10 +4243,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>您确定要更新
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; 吗?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -5372,7 +5362,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>像 YubiKey 这样的“漫游”身份验证器</target>
</trans-unit>
@ -5707,10 +5697,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;,类型为
<x id="0" equiv-text="${prompt.name}"/>"
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
<x id="2" equiv-text="${prompt.type}"/></target>
</trans-unit>
@ -5759,7 +5749,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>如果设置时长大于 0用户可以选择“保持登录”选项这将使用户的会话延长此处设置的时间。</target>
</trans-unit>
@ -6140,11 +6130,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>绑定阶段</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
<target>创建 &amp; 绑定阶段</target>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
@ -6889,21 +6874,11 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>自定义</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>流程与阶段</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>目录</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>令牌和应用程序密码</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
@ -7775,7 +7750,19 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
<target>静态拒绝流。要有效地使用此阶段,请在相应的绑定上禁用*规划时进行评估*。</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -2273,9 +2273,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>当前没有策略绑定到此对象。</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2674,10 +2671,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>创建一个新身份来源。</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>联盟和社交登录</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>身份来源既可以同步到authentik的数据库中也可以被用户用来进行身份验证和注册。</target>
@ -4603,9 +4596,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Bind 阶段</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5172,18 +5162,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>定制</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>流程和阶段</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>目录</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>令牌和应用程序密码</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>系统</target>
@ -5846,6 +5828,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -2273,9 +2273,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>No policies are currently bound to this object.</source>
<target>当前没有策略绑定到此对象。</target>
</trans-unit>
<trans-unit id="s6b66ad92d4c1a0a8">
<source>Create &amp; bind Policy</source>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
</trans-unit>
@ -2674,10 +2671,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Create a new source.</source>
<target>创建一个新身份来源。</target>
</trans-unit>
<trans-unit id="sf96b3cc66d2e25f8">
<source>Federation &amp; Social login</source>
<target>联盟和社交登录</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>身份来源既可以同步到authentik的数据库中也可以被用户用来进行身份验证和注册。</target>
@ -4602,9 +4595,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Bind stage</source>
<target>Bind 阶段</target>
</trans-unit>
<trans-unit id="se8eb190d8f084f80">
<source>Create &amp; bind Stage</source>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
</trans-unit>
@ -5171,18 +5161,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Customisation</source>
<target>定制</target>
</trans-unit>
<trans-unit id="s58398dbcff942947">
<source>Flows &amp; Stages</source>
<target>流程和阶段</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>目录</target>
</trans-unit>
<trans-unit id="sdf4e926513e26458">
<source>Tokens &amp; App passwords</source>
<target>令牌和应用程序密码</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>系统</target>
@ -5845,6 +5827,18 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
</body>
</file>

View File

@ -136,6 +136,37 @@ image:
- web/admin: clear other options depending on what the binding targets (#6703)
- web/admin: fix ak-toggle-group for policy and blueprint uses (#6687)
## Fixed in 2023.8.3
- core: bump celery from 5.3.1 to 5.3.4
- core: bump django from 4.2.4 to 4.2.5 (#6751)
- core: remove celery's duplicate max_tasks_per_child (#6840)
- policies/reputation: require either check to be enabled (#6764)
- providers/scim: check that a provider exists before starting scim task (#6841)
- root: fix broken celery dependency (#6744)
- root: lock node to 20.5 (#6776)
- sources/ldap: dont prefetch useless items (#6812)
- sources/ldap: fix FreeIPA nsaccountlock sync (#6745)
- sources/ldap: fix task timeout for ldap_sync_all and ldap_sync_single (#6809)
- stages/password: fix failed_attempts_before_cancel allowing one too m… (#6763)
- web/admin: fix application icon size (#6738)
- web/admin: fix not being able to unset flows (#6838)
- web/admin: fix not being able to unset certificates (#6767)
- web: don't import entire SourceViewPage in flow and user interface (#6761)
- web: replace ampersand (#6737)
## Fixed in 2023.8.4
- \*: fix [GHSA-rjvp-29xq-f62w](../security/GHSA-rjvp-29xq-f62w), Reported by [@devSparkle](https://github.com/devSparkle)
## Fixed in 2023.8.5
- security: fix [CVE-2023-48228](../../security/CVE-2023-48228.md), Reported by [@Sapd](https://github.com/Sapd) (#7666)
## Fixed in 2023.8.6
- providers/oauth2: fix [CVE-2024-21637](../../security/CVE-2024-21637.md), Reported by [@lauritzh](https://github.com/lauritzh) (#8104)
## API Changes
#### What's New

View File

@ -0,0 +1,61 @@
# CVE-2023-48228
_Reported by [@Sapd](https://github.com/Sapd)_
## OAuth2: Insufficient PKCE check
### Summary
When initialising a OAuth2 flow with a `code_challenge` and `code_method` (thus requesting PKCE), the SSO provider (authentik) **must** check if there is a matching **and** existing `code_verifier` during the token step.
authentik checks if the contents of code*verifier is matching \*\*\_ONLY*\*\* when it is provided. When it is left out completely, authentik simply accepts the token request with out it; even when the flow was started with a `code_challenge`.
### Patches
authentik 2023.8.5 and 2023.10.4 fix this issue.
### Details
The `code_verifier` is only checked when the user provides it. Note that in line 209 there is a check if the code_parameter is left out. But there is no check if the PKCE parameter simply was omitted WHEN the request was started with a `code_challenge_method`.
This oversight likely did not stem from a coding error but from a misinterpretation of the RFC, where the backward compatibility section may be somewhat confusing.
https://datatracker.ietf.org/doc/html/rfc7636#section-4.5
RFC7636 explicitly says in Section 4.5:
> The "code_challenge_method" is bound to the Authorization Code when
> the Authorization Code is issued. That is the method that the token
> endpoint MUST use to verify the "code_verifier".
Section 5, Compatibility
> Server implementations of this specification MAY accept OAuth2.0
> clients that do not implement this extension. If the "code_verifier"
> is not received from the client in the Authorization Request, servers
> supporting backwards compatibility revert to the OAuth 2.0 [[RFC6749](https://datatracker.ietf.org/doc/html/rfc6749)]
> protocol without this extension.
Section 5, Compatibility, allows server implementations of this specification to accept OAuth 2.0 clients that do not implement this extension. However, if a `code_verifier` is not received from the client in the Authorization Request, servers that support backward compatibility should revert to the standard OAuth 2.0 protocol sans this extension (including all steps).
It should be noted that this does not mean that the `code_verifier` check can be disregarded at any point if the initial request included `code_challenge` or `code_challenge_method`. Since Authentik supports PKCE, it **MUST** verify the code_verifier as described in Section 4.5 **AND** fail if it was not provided.
Ofc verification can be skipped if the original authorization request did not invoke PKCE (no `code_challenge_method` and no `code_challenge`).
Failure to check the `code_verifier` renders the PKCE flow ineffective. This vulnerability particularly endangers public or hybrid clients, as their `code` is deemed non-confidential.
While not explicitly stated in the standard, it is generally recommended that OAuth2 flows accepting public clients should enforce PKCE - at least when redirecting to a non HTTPS URL (like http or an app link).
### Impact
The vulnerability poses a high risk to both public and hybrid clients.
When for example a mobile app implements oauth2, a malicious app can simply also register the same in-app-link (e.g. `mycoolapp://oauth2`) for the redirect callback URL, possibly receiving `code` during callback. With PKCE working, a malicious app would still receive a `code` but the `code` would not work without the correct unhashed code-challenge.
This is especially problematic, because authentik claims to support PKCE, and a developer can expect that the proper checks are in place. Note that app-links cannot be protected by HTTPS or similar mechanisms.
Note also that this vulnerability poses a threat to confidential clients. Many confidential clients act as a proxy for OAuth2 API requests, typically from mobile apps or single-page applications. These proxies relay `code_challenge`, `code_challenge_method` (in auth request, which most libraries force and provide on default settings) and `code_verifier` in the token request unchanged and supplement the CLIENT_SECRET which only the relay knows. The relay can but does not have to check for an existing `code_verifier` as the standard does not define that PKCE can be ignored on confidential clients during the token request when the client requested PKCE during the authorization request.
An attacker could potentially gain full access to the application. If the code grants access to an admin account, the confidentiality, integrity, and availability of that application are compromised.
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

View File

@ -0,0 +1,39 @@
# CVE-2024-21637
_Reported by [@lauritzh](https://github.com/lauritzh)_
## XSS in Authentik via JavaScript-URI as Redirect URI and form_post Response Mode
### Summary
Given an OAuth2 provider configured with allowed redirect URIs set to `*` or `.*`, an attacker can send an OAuth Authorization request using `response_mode=form_post` and setting `redirect_uri` to a malicious URI, to capture authentik's session token.
### Patches
authentik 2023.8.6 and 2023.10.6 fix this issue.
### Impact
The impact depends on the attack scenario. In the following I will describe the two scenario that were identified for Authentik.
#### Redirect URI Misconfiguration
While advising that this may cause security issues, Authentik generally allows wildcards as Redirect URI. Therefore, using a wildcard-only effectively allowing arbitrary URLS is possible misconfiguration that may be present in real-world instances.
In such cases, unauthenticated and unprivileged attackers can perform the above described actions.
### User with (only) App Administration Permissions
A more likely scenario is an administrative user (e.g. a normal developer) having only permissions to manage applications.
This relatively user could use the described attacks to perform a privilege escalation.
### Workaround
It is recommended to upgrade to the patched version of authentik. If not possible, ensure that OAuth2 providers do not use a wildcard (`*` or `.*`) value as allowed redirect URI setting. (This is _not_ exploitable if part of the redirect URI has a wildcard, for example `https://foo-.*\.bar\.com`)
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

View File

@ -0,0 +1,27 @@
# CVE-2024-23647
_Reported by [@pieterphilippaerts](https://github.com/pieterphilippaerts)_
## PKCE downgrade attack in authentik
## Summary
PKCE is a very important countermeasure in OAuth2 , both for public and confidential clients. It protects against CSRF attacks and code injection attacks. Because of this bug, an attacker can circumvent the protection PKCE offers.
## Patches
authentik 2023.8.7 and 2023.10.7 fix this issue.
## Details
There is a bug in our implementation of PKCE that allows an attacker to circumvent the protection that PKCE offers. PKCE adds the `code_challenge parameter to the authorization request and adds the `code_verifier parameter to the token request. We recently fixed a downgrade attack (in v2023.8.5 and 2023.10.4) where if the attacker removed the `code_verifier parameter in the token request, authentik would allow the request to pass, thus circumventing PKCEs protection. However, in the latest version of the software, another downgrade scenario is still possible: if the attacker removes the `code_challenge parameter from the authorization request, authentik will also not do the PKCE check.
Note that this type of downgrade enables an attacker to perform a code injection attack, even if the OAuth client is using PKCE (which is supposed to protect against code injection attacks). To start the attack, the attacker must initiate the authorization process without that `code_challenge parameter in the authorization request. But this is easy to do (just use a phishing site or email to trick the user into clicking on a link that the attacker controls the authorization link without that `code_challenge parameter).
The OAuth BCP (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics) explicitly mentions this particular attack in section 2.1.1: “Authorization servers MUST mitigate PKCE Downgrade Attacks by ensuring that a token request containing a code_verifier parameter is accepted only if a code_challenge parameter was present in the authorization request, see Section 4.8.2 for details.”
## For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

View File

@ -0,0 +1,27 @@
# GHSA-rjvp-29xq-f62w
_Reported by [@devSparkle](https://github.com/devSparkle)_
## Potential Installation takeover when default admin user is deleted
### Summary
In the affected versions, when the default admin user has been deleted, it is potentially possible for an attacker to set the password of the default admin user without any authentication.
### Patches
authentik 2023.8.4 and 2023.10.2 fix this issue, for other versions the workaround can be used.
### Impact
authentik uses a blueprint to create the default admin user, which can also optionally set the default admin users' password from an environment variable. When the user is deleted, the `initial-setup` flow used to configure authentik after the first installation becomes available again.
### Workarounds
Ensure the default admin user (Username `akadmin`) exists and has a password set. It is recommended to use a very strong password for this user, and store it in a secure location like a password manager. It is also possible to deactivate the user to prevent any logins as akadmin.
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

View File

@ -362,6 +362,10 @@ const docsSidebar = {
},
items: [
"security/policy",
"security/CVE-2024-23647",
"security/CVE-2024-21637",
"security/CVE-2023-48228",
"security/GHSA-rjvp-29xq-f62w",
"security/CVE-2023-39522",
"security/CVE-2023-36456",
"security/2023-06-cure53",