Compare commits

...

25 Commits

Author SHA1 Message Date
540c5864ee ci: push releases to new dockerhub
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-12-18 17:35:22 +01:00
821f06ffdf translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#12393)
Translate locale/en/LC_MESSAGES/django.po in fr

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'fr'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-12-18 15:52:56 +00:00
e83d040a48 translate: Updates for file web/xliff/en.xlf in fr (#12394)
Translate web/xliff/en.xlf in fr

100% translated source file: 'web/xliff/en.xlf'
on 'fr'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-12-18 15:32:56 +00:00
9affd90850 root: add locale to codeowners (#12392)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-12-18 15:56:46 +01:00
80d84cb03f website/integrations: update argocd terraform examples (#12370) 2024-12-18 14:21:31 +00:00
a9cc5fdafe core, web: update translations (#12390)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-12-18 15:17:49 +01:00
b45109afce web: bump API Client version (#12391)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2024-12-18 13:59:24 +00:00
c8711d9f8f website/docs: 2024.12 release notes (#12300)
Co-authored-by: Tana M Berry <tana@goauthentik.com>
2024-12-18 13:39:17 +00:00
40a7135c0c core: app entitlements (#12090)
* core: initial app entitlements

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

* base off of pbm

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

* add tests and oauth2

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

* add to proxy

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

* rewrite to use bindings

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

* make policy bindings form and list more customizable

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

* fix tests

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

* double fix

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

* refine permissions

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

* add missing rbac modal to app entitlements

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

* separate scope for app entitlements

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

* include entitlements mapping in proxy

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

* fix tests

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

* add API validation to prevent policies from being bound to entitlements

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

* make preview

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

* add initial docs

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

* fix

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

* remove duplicate docs

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-12-18 14:32:44 +01:00
675a4a6788 translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#12388)
Translate locale/en/LC_MESSAGES/django.po in it

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-12-18 13:26:45 +00:00
98b5b75f29 blueprints: add AtIndex tag (#12386) 2024-12-18 13:10:37 +00:00
22b0a1bd23 web: bump API Client version (#12387)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2024-12-18 13:57:38 +01:00
1a1d499833 sources/oauth: allow creation of user connection objects with parameters (#12195)
* sources/oauth: allow creation of user connection objects with parameters

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

* fix web

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

* tix tests

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

* add for all

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

* align

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-12-18 13:28:22 +01:00
1573cfbaa1 website: bump docusaurus-theme-openapi-docs from 4.3.0 to 4.3.1 in /website (#12373)
website: bump docusaurus-theme-openapi-docs in /website

Bumps [docusaurus-theme-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-theme-openapi-docs) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.1/packages/docusaurus-theme-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-theme-openapi-docs
  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>
2024-12-18 13:19:02 +01:00
b88ce32111 website: bump aws-cdk from 2.173.1 to 2.173.2 in /website (#12374)
Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.173.1 to 2.173.2.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.173.2/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-type: direct:development
  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>
2024-12-18 13:17:31 +01:00
a1965ceada website: bump docusaurus-plugin-openapi-docs from 4.3.0 to 4.3.1 in /website (#12375)
website: bump docusaurus-plugin-openapi-docs in /website

Bumps [docusaurus-plugin-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-plugin-openapi-docs) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.1/packages/docusaurus-plugin-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-plugin-openapi-docs
  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>
2024-12-18 13:17:23 +01:00
9c536a1b4b core: bump django-pglock from 1.7.0 to 1.7.1 (#12376)
Bumps [django-pglock](https://github.com/AmbitionEng/django-pglock) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/AmbitionEng/django-pglock/releases)
- [Changelog](https://github.com/AmbitionEng/django-pglock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/AmbitionEng/django-pglock/compare/1.7.0...1.7.1)

---
updated-dependencies:
- dependency-name: django-pglock
  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>
2024-12-18 13:13:37 +01:00
f3e0ff2833 core: bump google-api-python-client from 2.154.0 to 2.155.0 (#12377)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.154.0 to 2.155.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.154.0...v2.155.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-18 13:13:24 +01:00
06dc47b582 core: bump aws-cdk-lib from 2.172.0 to 2.173.2 (#12378)
Bumps [aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.172.0 to 2.173.2.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/compare/v2.172.0...v2.173.2)

---
updated-dependencies:
- dependency-name: aws-cdk-lib
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-18 13:13:18 +01:00
a4bf24a039 core: bump pdoc from 15.0.0 to 15.0.1 (#12379)
* core: bump pdoc from 15.0.0 to 15.0.1

Bumps [pdoc](https://github.com/mitmproxy/pdoc) from 15.0.0 to 15.0.1.
- [Changelog](https://github.com/mitmproxy/pdoc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mitmproxy/pdoc/compare/v15...v15.0.1)

---
updated-dependencies:
- dependency-name: pdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-18 13:12:49 +01:00
1715c3e268 core: bump ruff from 0.8.2 to 0.8.3 (#12380)
* core: bump ruff from 0.8.2 to 0.8.3

Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.2 to 0.8.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.8.2...0.8.3)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-18 13:11:48 +01:00
feb3be7cee core: bump uvicorn from 0.32.1 to 0.34.0 (#12381)
* core: bump uvicorn from 0.32.1 to 0.34.0

Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.32.1 to 0.34.0.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.32.1...0.34.0)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-18 13:11:07 +01:00
db05232f12 core: bump twilio from 9.3.8 to 9.4.1 (#12382)
* core: bump twilio from 9.3.8 to 9.4.1

Bumps [twilio](https://github.com/twilio/twilio-python) from 9.3.8 to 9.4.1.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/9.3.8...9.4.1)

---
updated-dependencies:
- dependency-name: twilio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-18 13:10:46 +01:00
ebfa7dbcfc web/admin: fix prompt stage wording (#12384)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-12-18 13:07:51 +01:00
8c4dab7399 sources/saml: fix redirect not kept through SAML Source (#12372)
* fix missing name in tests

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

* fix redirect lost with saml source

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-12-18 13:07:17 +01:00
84 changed files with 3136 additions and 606 deletions

View File

@ -26,12 +26,17 @@ jobs:
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with:
image-name: ghcr.io/goauthentik/server,beryju/authentik
- name: Docker Login Registry
image-name: ghcr.io/goauthentik/server,beryju/authentik,authentik/server
- name: Login to Docker Registry (legacy)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to Docker Registry (org)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_CORP_USERNAME }}
password: ${{ secrets.DOCKER_CORP_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
@ -92,16 +97,21 @@ jobs:
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with:
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }}
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }},authentik/${{ matrix.type }}
- name: make empty clients
run: |
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
- name: Docker Login Registry
- name: Login to Docker Registry (legacy)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to Docker Registry (org)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_CORP_USERNAME }}
password: ${{ secrets.DOCKER_CORP_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:

View File

@ -33,7 +33,8 @@
"!If sequence",
"!Index scalar",
"!KeyOf scalar",
"!Value scalar"
"!Value scalar",
"!AtIndex scalar"
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifierEnding": "index",

View File

@ -25,6 +25,9 @@ CODEOWNERS @goauthentik/infrastructure
# Web
web/ @goauthentik/frontend
tests/wdio/ @goauthentik/frontend
# Locale
locale/ @goauthentik/backend @goauthentik/frontend
web/xliff/ @goauthentik/backend @goauthentik/frontend
# Docs & Website
website/ @goauthentik/docs
CODE_OF_CONDUCT.md @goauthentik/docs

View File

@ -146,6 +146,10 @@ entries:
]
]
nested_context: !Context context2
at_index_sequence: !AtIndex [!Context sequence, 0]
at_index_sequence_default: !AtIndex [!Context sequence, 100, "non existent"]
at_index_mapping: !AtIndex [!Context mapping, "key2"]
at_index_mapping_default: !AtIndex [!Context mapping, "invalid", "non existent"]
identifiers:
name: test
conditions:

View File

@ -215,6 +215,10 @@ class TestBlueprintsV1(TransactionTestCase):
},
"nested_context": "context-nested-value",
"env_null": None,
"at_index_sequence": "foo",
"at_index_sequence_default": "non existent",
"at_index_mapping": 2,
"at_index_mapping_default": "non existent",
}
).exists()
)

View File

@ -24,6 +24,10 @@ from authentik.lib.sentry import SentryIgnoredException
from authentik.policies.models import PolicyBindingModel
class UNSET:
"""Used to test whether a key has not been set."""
def get_attrs(obj: SerializerModel) -> dict[str, Any]:
"""Get object's attributes via their serializer, and convert it to a normal dict"""
serializer: Serializer = obj.serializer(obj)
@ -556,6 +560,53 @@ class Value(EnumeratedItem):
raise EntryInvalidError.from_entry(f"Empty/invalid context: {context}", entry) from exc
class AtIndex(YAMLTag):
"""Get value at index of a sequence or mapping"""
obj: YAMLTag | dict | list | tuple
attribute: int | str | YAMLTag
default: Any | UNSET
def __init__(self, loader: "BlueprintLoader", node: SequenceNode) -> None:
super().__init__()
self.obj = loader.construct_object(node.value[0])
self.attribute = loader.construct_object(node.value[1])
if len(node.value) == 2: # noqa: PLR2004
self.default = UNSET
else:
self.default = loader.construct_object(node.value[2])
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
if isinstance(self.obj, YAMLTag):
obj = self.obj.resolve(entry, blueprint)
else:
obj = self.obj
if isinstance(self.attribute, YAMLTag):
attribute = self.attribute.resolve(entry, blueprint)
else:
attribute = self.attribute
if isinstance(obj, list | tuple):
try:
return obj[attribute]
except TypeError as exc:
raise EntryInvalidError.from_entry(
f"Invalid index for list: {attribute}", entry
) from exc
except IndexError as exc:
if self.default is UNSET:
raise EntryInvalidError.from_entry(
f"Index out of range: {attribute}", entry
) from exc
return self.default
if attribute in obj:
return obj[attribute]
else:
if self.default is UNSET:
raise EntryInvalidError.from_entry(f"Key does not exist: {attribute}", entry)
return self.default
class BlueprintDumper(SafeDumper):
"""Dump dataclasses to yaml"""
@ -606,6 +657,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!Enumerate", Enumerate)
self.add_constructor("!Value", Value)
self.add_constructor("!Index", Index)
self.add_constructor("!AtIndex", AtIndex)
class EntryInvalidError(SentryIgnoredException):

View File

@ -0,0 +1,54 @@
"""Application Roles API Viewset"""
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer
from authentik.core.models import (
Application,
ApplicationEntitlement,
User,
)
class ApplicationEntitlementSerializer(ModelSerializer):
"""ApplicationEntitlement Serializer"""
def validate_app(self, app: Application) -> Application:
"""Ensure user has permission to view"""
user: User = self._context["request"].user
if user.has_perm("view_application", app) or user.has_perm(
"authentik_core.view_application"
):
return app
raise ValidationError(_("User does not have access to application."), code="invalid")
class Meta:
model = ApplicationEntitlement
fields = [
"pbm_uuid",
"name",
"app",
"attributes",
]
class ApplicationEntitlementViewSet(UsedByMixin, ModelViewSet):
"""ApplicationEntitlement Viewset"""
queryset = ApplicationEntitlement.objects.all()
serializer_class = ApplicationEntitlementSerializer
search_fields = [
"pbm_uuid",
"name",
"app",
"attributes",
]
filterset_fields = [
"pbm_uuid",
"name",
"app",
]
ordering = ["name"]

View File

@ -159,9 +159,9 @@ class SourceViewSet(
class UserSourceConnectionSerializer(SourceSerializer):
"""OAuth Source Serializer"""
"""User source connection"""
source = SourceSerializer(read_only=True)
source_obj = SourceSerializer(read_only=True, source="source")
class Meta:
model = UserSourceConnection
@ -169,10 +169,10 @@ class UserSourceConnectionSerializer(SourceSerializer):
"pk",
"user",
"source",
"source_obj",
"created",
]
extra_kwargs = {
"user": {"read_only": True},
"created": {"read_only": True},
}
@ -197,9 +197,9 @@ class UserSourceConnectionViewSet(
class GroupSourceConnectionSerializer(SourceSerializer):
"""Group Source Connection Serializer"""
"""Group Source Connection"""
source = SourceSerializer(read_only=True)
source_obj = SourceSerializer(read_only=True)
class Meta:
model = GroupSourceConnection
@ -207,12 +207,11 @@ class GroupSourceConnectionSerializer(SourceSerializer):
"pk",
"group",
"source",
"source_obj",
"identifier",
"created",
]
extra_kwargs = {
"group": {"read_only": True},
"identifier": {"read_only": True},
"created": {"read_only": True},
}

View File

@ -22,7 +22,7 @@ from authentik.blueprints.v1.common import (
from authentik.blueprints.v1.importer import Importer
from authentik.core.api.applications import ApplicationSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Provider
from authentik.core.models import Application, Provider
from authentik.lib.utils.reflection import all_subclasses
from authentik.policies.api.bindings import PolicyBindingSerializer
@ -51,6 +51,13 @@ class TransactionProviderField(DictField):
class TransactionPolicyBindingSerializer(PolicyBindingSerializer):
"""PolicyBindingSerializer which does not require target as target is set implicitly"""
def validate(self, attrs):
# As the PolicyBindingSerializer checks that the correct things can be bound to a target
# but we don't have a target here as that's set by the blueprint, pass in an empty app
# which will have the correct allowed combination of group/user/policy.
attrs["target"] = Application()
return super().validate(attrs)
class Meta(PolicyBindingSerializer.Meta):
fields = [x for x in PolicyBindingSerializer.Meta.fields if x != "target"]

View File

@ -0,0 +1,45 @@
# Generated by Django 5.0.9 on 2024-11-20 15:16
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0040_provider_invalidation_flow"),
("authentik_policies", "0011_policybinding_failure_result_and_more"),
]
operations = [
migrations.CreateModel(
name="ApplicationEntitlement",
fields=[
(
"policybindingmodel_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_policies.policybindingmodel",
),
),
("attributes", models.JSONField(blank=True, default=dict)),
("name", models.TextField()),
(
"app",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="authentik_core.application"
),
),
],
options={
"verbose_name": "Application Entitlement",
"verbose_name_plural": "Application Entitlements",
"unique_together": {("app", "name")},
},
bases=("authentik_policies.policybindingmodel", models.Model),
),
]

View File

@ -314,6 +314,32 @@ class User(SerializerModel, GuardianUserMixin, AttributesMixin, AbstractUser):
always_merger.merge(final_attributes, self.attributes)
return final_attributes
def app_entitlements(self, app: "Application | None") -> QuerySet["ApplicationEntitlement"]:
"""Get all entitlements this user has for `app`."""
if not app:
return []
all_groups = self.all_groups()
qs = app.applicationentitlement_set.filter(
Q(
Q(bindings__user=self) | Q(bindings__group__in=all_groups),
bindings__negate=False,
)
| Q(
Q(~Q(bindings__user=self), bindings__user__isnull=False)
| Q(~Q(bindings__group__in=all_groups), bindings__group__isnull=False),
bindings__negate=True,
),
bindings__enabled=True,
).order_by("name")
return qs
def app_entitlements_attributes(self, app: "Application | None") -> dict:
"""Get a dictionary containing all merged attributes from app entitlements for `app`."""
final_attributes = {}
for attrs in self.app_entitlements(app).values_list("attributes", flat=True):
always_merger.merge(final_attributes, attrs)
return final_attributes
@property
def serializer(self) -> Serializer:
from authentik.core.api.users import UserSerializer
@ -581,6 +607,31 @@ class Application(SerializerModel, PolicyBindingModel):
verbose_name_plural = _("Applications")
class ApplicationEntitlement(AttributesMixin, SerializerModel, PolicyBindingModel):
"""Application-scoped entitlement to control authorization in an application"""
name = models.TextField()
app = models.ForeignKey(Application, on_delete=models.CASCADE)
class Meta:
verbose_name = _("Application Entitlement")
verbose_name_plural = _("Application Entitlements")
unique_together = (("app", "name"),)
def __str__(self):
return f"Application Entitlement {self.name} for app {self.app_id}"
@property
def serializer(self) -> type[Serializer]:
from authentik.core.api.application_entitlements import ApplicationEntitlementSerializer
return ApplicationEntitlementSerializer
def supported_policy_binding_targets(self):
return ["group", "user"]
class SourceUserMatchingModes(models.TextChoices):
"""Different modes a source can handle new/returning users"""

View File

@ -238,13 +238,7 @@ class SourceFlowManager:
self.request.GET,
flow_slug=flow_slug,
)
# Ensure redirect is carried through when user was trying to
# authorize application
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
NEXT_ARG_NAME, "authentik_core:if-user"
)
if PLAN_CONTEXT_REDIRECT not in flow_context:
flow_context[PLAN_CONTEXT_REDIRECT] = final_redirect
flow_context.setdefault(PLAN_CONTEXT_REDIRECT, final_redirect)
if not flow:
return bad_request_message(

View File

@ -0,0 +1,153 @@
"""Test Application Entitlements API"""
from django.urls import reverse
from guardian.shortcuts import assign_perm
from rest_framework.test import APITestCase
from authentik.core.models import Application, ApplicationEntitlement, Group
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_user
from authentik.lib.generators import generate_id
from authentik.policies.dummy.models import DummyPolicy
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.models import OAuth2Provider
class TestApplicationEntitlements(APITestCase):
"""Test application entitlements"""
def setUp(self) -> None:
self.user = create_test_user()
self.other_user = create_test_user()
self.provider = OAuth2Provider.objects.create(
name="test",
authorization_flow=create_test_flow(),
)
self.app: Application = Application.objects.create(
name=generate_id(),
slug=generate_id(),
provider=self.provider,
)
def test_user(self):
"""Test user-direct assignment"""
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
PolicyBinding.objects.create(target=ent, user=self.user, order=0)
ents = self.user.app_entitlements(self.app)
self.assertEqual(len(ents), 1)
self.assertEqual(ents[0].name, ent.name)
def test_group(self):
"""Test direct group"""
group = Group.objects.create(name=generate_id())
self.user.ak_groups.add(group)
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
PolicyBinding.objects.create(target=ent, group=group, order=0)
ents = self.user.app_entitlements(self.app)
self.assertEqual(len(ents), 1)
self.assertEqual(ents[0].name, ent.name)
def test_group_indirect(self):
"""Test indirect group"""
parent = Group.objects.create(name=generate_id())
group = Group.objects.create(name=generate_id(), parent=parent)
self.user.ak_groups.add(group)
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
PolicyBinding.objects.create(target=ent, group=parent, order=0)
ents = self.user.app_entitlements(self.app)
self.assertEqual(len(ents), 1)
self.assertEqual(ents[0].name, ent.name)
def test_negate_user(self):
"""Test with negate flag"""
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
PolicyBinding.objects.create(target=ent, user=self.other_user, order=0, negate=True)
ents = self.user.app_entitlements(self.app)
self.assertEqual(len(ents), 1)
self.assertEqual(ents[0].name, ent.name)
def test_negate_group(self):
"""Test with negate flag"""
other_group = Group.objects.create(name=generate_id())
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
PolicyBinding.objects.create(target=ent, group=other_group, order=0, negate=True)
ents = self.user.app_entitlements(self.app)
self.assertEqual(len(ents), 1)
self.assertEqual(ents[0].name, ent.name)
def test_api_perms_global(self):
"""Test API creation with global permissions"""
assign_perm("authentik_core.add_applicationentitlement", self.user)
assign_perm("authentik_core.view_application", self.user)
self.client.force_login(self.user)
res = self.client.post(
reverse("authentik_api:applicationentitlement-list"),
data={
"name": generate_id(),
"app": self.app.pk,
},
)
self.assertEqual(res.status_code, 201)
def test_api_perms_scoped(self):
"""Test API creation with scoped permissions"""
assign_perm("authentik_core.add_applicationentitlement", self.user)
assign_perm("authentik_core.view_application", self.user, self.app)
self.client.force_login(self.user)
res = self.client.post(
reverse("authentik_api:applicationentitlement-list"),
data={
"name": generate_id(),
"app": self.app.pk,
},
)
self.assertEqual(res.status_code, 201)
def test_api_perms_missing(self):
"""Test API creation with no permissions"""
assign_perm("authentik_core.add_applicationentitlement", self.user)
self.client.force_login(self.user)
res = self.client.post(
reverse("authentik_api:applicationentitlement-list"),
data={
"name": generate_id(),
"app": self.app.pk,
},
)
self.assertEqual(res.status_code, 400)
self.assertJSONEqual(res.content, {"app": ["User does not have access to application."]})
def test_api_bindings_policy(self):
"""Test that API doesn't allow policies to be bound to this"""
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
policy = DummyPolicy.objects.create(name=generate_id())
admin = create_test_admin_user()
self.client.force_login(admin)
response = self.client.post(
reverse("authentik_api:policybinding-list"),
data={
"target": ent.pbm_uuid,
"policy": policy.pk,
"order": 0,
},
)
self.assertJSONEqual(
response.content.decode(),
{"non_field_errors": ["One of 'group', 'user' must be set."]},
)
def test_api_bindings_group(self):
"""Test that API doesn't allow policies to be bound to this"""
ent = ApplicationEntitlement.objects.create(app=self.app, name=generate_id())
group = Group.objects.create(name=generate_id())
admin = create_test_admin_user()
self.client.force_login(admin)
response = self.client.post(
reverse("authentik_api:policybinding-list"),
data={
"target": ent.pbm_uuid,
"group": group.pk,
"order": 0,
},
)
self.assertEqual(response.status_code, 201)
self.assertTrue(PolicyBinding.objects.filter(target=ent.pbm_uuid).exists())

View File

@ -6,6 +6,7 @@ from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import path
from authentik.core.api.application_entitlements import ApplicationEntitlementViewSet
from authentik.core.api.applications import ApplicationViewSet
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
from authentik.core.api.devices import AdminDeviceViewSet, DeviceViewSet
@ -69,6 +70,7 @@ urlpatterns = [
api_urlpatterns = [
("core/authenticated_sessions", AuthenticatedSessionViewSet),
("core/applications", ApplicationViewSet),
("core/application_entitlements", ApplicationEntitlementViewSet),
path(
"core/transactional/applications/",
TransactionalApplicationView.as_view(),

View File

@ -84,19 +84,17 @@ class PolicyBindingSerializer(ModelSerializer):
def validate(self, attrs: OrderedDict) -> OrderedDict:
"""Check that either policy, group or user is set."""
count = sum(
[
bool(attrs.get("policy", None)),
bool(attrs.get("group", None)),
bool(attrs.get("user", None)),
]
)
target: PolicyBindingModel = attrs.get("target")
supported = target.supported_policy_binding_targets()
supported.sort()
count = sum([bool(attrs.get(x, None)) for x in supported])
invalid = count > 1
empty = count < 1
warning = ", ".join(f"'{x}'" for x in supported)
if invalid:
raise ValidationError("Only one of 'policy', 'group' or 'user' can be set.")
raise ValidationError(f"Only one of {warning} can be set.")
if empty:
raise ValidationError("One of 'policy', 'group' or 'user' must be set.")
raise ValidationError(f"One of {warning} must be set.")
return attrs

View File

@ -1,4 +1,6 @@
# Generated by Django 4.2.5 on 2023-09-13 18:07
import authentik.lib.models
import django.db.models.deletion
from django.db import migrations, models
@ -23,4 +25,13 @@ class Migration(migrations.Migration):
default=30, help_text="Timeout after which Policy execution is terminated."
),
),
migrations.AlterField(
model_name="policybinding",
name="target",
field=authentik.lib.models.InheritanceForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="bindings",
to="authentik_policies.policybindingmodel",
),
),
]

View File

@ -47,6 +47,10 @@ class PolicyBindingModel(models.Model):
def __str__(self) -> str:
return f"PolicyBindingModel {self.pbm_uuid}"
def supported_policy_binding_targets(self):
"""Return the list of objects that can be bound to this object."""
return ["policy", "user", "group"]
class PolicyBinding(SerializerModel):
"""Relationship between a Policy and a PolicyBindingModel."""
@ -81,7 +85,9 @@ class PolicyBinding(SerializerModel):
blank=True,
)
target = InheritanceForeignKey(PolicyBindingModel, on_delete=models.CASCADE, related_name="+")
target = InheritanceForeignKey(
PolicyBindingModel, on_delete=models.CASCADE, related_name="bindings"
)
negate = models.BooleanField(
default=False,
help_text=_("Negates the outcome of the policy. Messages are unaffected."),

View File

@ -38,7 +38,7 @@ class TestBindingsAPI(APITestCase):
)
self.assertJSONEqual(
response.content.decode(),
{"non_field_errors": ["Only one of 'policy', 'group' or 'user' can be set."]},
{"non_field_errors": ["Only one of 'group', 'policy', 'user' can be set."]},
)
def test_invalid_too_little(self):
@ -49,5 +49,5 @@ class TestBindingsAPI(APITestCase):
)
self.assertJSONEqual(
response.content.decode(),
{"non_field_errors": ["One of 'policy', 'group' or 'user' must be set."]},
{"non_field_errors": ["One of 'group', 'policy', 'user' must be set."]},
)

View File

@ -127,6 +127,7 @@ class Traefik3MiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]
authResponseHeaders=[
"X-authentik-username",
"X-authentik-groups",
"X-authentik-entitlements",
"X-authentik-email",
"X-authentik-name",
"X-authentik-uid",

View File

@ -147,6 +147,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
"goauthentik.io/providers/oauth2/scope-openid",
"goauthentik.io/providers/oauth2/scope-profile",
"goauthentik.io/providers/oauth2/scope-email",
"goauthentik.io/providers/oauth2/scope-entitlements",
"goauthentik.io/providers/proxy/scope-proxy",
]
)

View File

@ -17,6 +17,7 @@ class TestMetadataProcessor(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.source = SAMLSource.objects.create(
name=generate_id(),
slug=generate_id(),
issuer="authentik",
signing_kp=create_test_cert(),

View File

@ -28,6 +28,7 @@ class TestPropertyMappings(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.source = SAMLSource.objects.create(
name=generate_id(),
slug=generate_id(),
issuer="authentik",
allow_idp_initiated=True,

View File

@ -20,6 +20,7 @@ class TestResponseProcessor(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.source = SAMLSource.objects.create(
name=generate_id(),
slug=generate_id(),
issuer="authentik",
allow_idp_initiated=True,

View File

@ -0,0 +1,88 @@
"""SAML Source tests"""
from base64 import b64encode
from django.test import RequestFactory, TestCase
from django.urls import reverse
from authentik.core.tests.utils import create_test_flow
from authentik.flows.planner import PLAN_CONTEXT_REDIRECT, FlowPlan
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
from authentik.sources.saml.models import SAMLSource
class TestViews(TestCase):
"""Test SAML Views"""
def setUp(self):
self.factory = RequestFactory()
self.source = SAMLSource.objects.create(
name=generate_id(),
slug=generate_id(),
issuer="authentik",
allow_idp_initiated=True,
pre_authentication_flow=create_test_flow(),
)
def test_enroll(self):
"""Enroll"""
flow = create_test_flow()
self.source.enrollment_flow = flow
self.source.save()
response = self.client.post(
reverse(
"authentik_sources_saml:acs",
kwargs={
"source_slug": self.source.slug,
},
),
data={
"SAMLResponse": b64encode(
load_fixture("fixtures/response_success.xml").encode()
).decode()
},
)
self.assertEqual(response.status_code, 302)
self.assertRedirects(
response, reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug})
)
plan: FlowPlan = self.client.session.get(SESSION_KEY_PLAN)
self.assertIsNotNone(plan)
def test_enroll_redirect(self):
"""Enroll when attempting to access a provider"""
initial_redirect = f"http://{generate_id()}"
session = self.client.session
old_plan = FlowPlan(generate_id())
old_plan.context[PLAN_CONTEXT_REDIRECT] = initial_redirect
session[SESSION_KEY_PLAN] = old_plan
session.save()
flow = create_test_flow()
self.source.enrollment_flow = flow
self.source.save()
response = self.client.post(
reverse(
"authentik_sources_saml:acs",
kwargs={
"source_slug": self.source.slug,
},
),
data={
"SAMLResponse": b64encode(
load_fixture("fixtures/response_success.xml").encode()
).decode()
},
)
self.assertEqual(response.status_code, 302)
self.assertRedirects(
response, reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug})
)
plan: FlowPlan = self.client.session.get(SESSION_KEY_PLAN)
self.assertIsNotNone(plan)
self.assertEqual(plan.context.get(PLAN_CONTEXT_REDIRECT), initial_redirect)

View File

@ -28,10 +28,11 @@ from authentik.flows.planner import (
PLAN_CONTEXT_REDIRECT,
PLAN_CONTEXT_SOURCE,
PLAN_CONTEXT_SSO,
FlowPlan,
FlowPlanner,
)
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
from authentik.lib.views import bad_request_message
from authentik.providers.saml.utils.encoding import nice64
from authentik.sources.saml.exceptions import MissingSAMLResponse, UnsupportedNameIDFormat
@ -148,12 +149,15 @@ class ACSView(View):
processor = ResponseProcessor(source, request)
try:
processor.parse()
except MissingSAMLResponse as exc:
return bad_request_message(request, str(exc))
except VerificationError as exc:
except (MissingSAMLResponse, VerificationError) as exc:
return bad_request_message(request, str(exc))
try:
if SESSION_KEY_PLAN in request.session:
plan: FlowPlan = self.request.session[SESSION_KEY_PLAN]
plan_redirect = plan.context.get(PLAN_CONTEXT_REDIRECT)
if plan_redirect:
self.request.session[SESSION_KEY_GET] = {NEXT_ARG_NAME: plan_redirect}
return processor.prepare_flow_manager().get_flow()
except (UnsupportedNameIDFormat, ValueError) as exc:
return bad_request_message(request, str(exc))

View File

@ -3201,6 +3201,46 @@
}
}
},
{
"type": "object",
"required": [
"model",
"identifiers"
],
"properties": {
"model": {
"const": "authentik_core.applicationentitlement"
},
"id": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"absent",
"present",
"created",
"must_created"
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"permissions": {
"$ref": "#/$defs/model_authentik_core.applicationentitlement_permissions"
},
"attrs": {
"$ref": "#/$defs/model_authentik_core.applicationentitlement"
},
"identifiers": {
"$ref": "#/$defs/model_authentik_core.applicationentitlement"
}
}
},
{
"type": "object",
"required": [
@ -4640,6 +4680,7 @@
"authentik_core.group",
"authentik_core.user",
"authentik_core.application",
"authentik_core.applicationentitlement",
"authentik_core.token",
"authentik_enterprise.license",
"authentik_providers_google_workspace.googleworkspaceprovider",
@ -6369,6 +6410,7 @@
"authentik_brands.delete_brand",
"authentik_brands.view_brand",
"authentik_core.add_application",
"authentik_core.add_applicationentitlement",
"authentik_core.add_authenticatedsession",
"authentik_core.add_group",
"authentik_core.add_groupsourceconnection",
@ -6381,6 +6423,7 @@
"authentik_core.add_usersourceconnection",
"authentik_core.assign_user_permissions",
"authentik_core.change_application",
"authentik_core.change_applicationentitlement",
"authentik_core.change_authenticatedsession",
"authentik_core.change_group",
"authentik_core.change_groupsourceconnection",
@ -6391,6 +6434,7 @@
"authentik_core.change_user",
"authentik_core.change_usersourceconnection",
"authentik_core.delete_application",
"authentik_core.delete_applicationentitlement",
"authentik_core.delete_authenticatedsession",
"authentik_core.delete_group",
"authentik_core.delete_groupsourceconnection",
@ -6406,6 +6450,7 @@
"authentik_core.reset_user_password",
"authentik_core.unassign_user_permissions",
"authentik_core.view_application",
"authentik_core.view_applicationentitlement",
"authentik_core.view_authenticatedsession",
"authentik_core.view_group",
"authentik_core.view_groupsourceconnection",
@ -7170,6 +7215,10 @@
"type": "integer",
"title": "User"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
@ -7212,6 +7261,20 @@
"model_authentik_sources_kerberos.groupkerberossourceconnection": {
"type": "object",
"properties": {
"group": {
"type": "string",
"format": "uuid",
"title": "Group"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
"title": "Identifier"
},
"icon": {
"type": "string",
"minLength": 1,
@ -7755,6 +7818,14 @@
"model_authentik_sources_oauth.useroauthsourceconnection": {
"type": "object",
"properties": {
"user": {
"type": "integer",
"title": "User"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"maxLength": 255,
@ -7805,6 +7876,20 @@
"model_authentik_sources_oauth.groupoauthsourceconnection": {
"type": "object",
"properties": {
"group": {
"type": "string",
"format": "uuid",
"title": "Group"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
"title": "Identifier"
},
"icon": {
"type": "string",
"minLength": 1,
@ -8038,6 +8123,14 @@
"model_authentik_sources_plex.userplexsourceconnection": {
"type": "object",
"properties": {
"user": {
"type": "integer",
"title": "User"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
@ -8085,6 +8178,20 @@
"model_authentik_sources_plex.groupplexsourceconnection": {
"type": "object",
"properties": {
"group": {
"type": "string",
"format": "uuid",
"title": "Group"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
"title": "Identifier"
},
"icon": {
"type": "string",
"minLength": 1,
@ -8395,6 +8502,14 @@
"model_authentik_sources_saml.usersamlsourceconnection": {
"type": "object",
"properties": {
"user": {
"type": "integer",
"title": "User"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
@ -8437,6 +8552,20 @@
"model_authentik_sources_saml.groupsamlsourceconnection": {
"type": "object",
"properties": {
"group": {
"type": "string",
"format": "uuid",
"title": "Group"
},
"source": {
"type": "integer",
"title": "Source"
},
"identifier": {
"type": "string",
"minLength": 1,
"title": "Identifier"
},
"icon": {
"type": "string",
"minLength": 1,
@ -12530,6 +12659,7 @@
"authentik_brands.delete_brand",
"authentik_brands.view_brand",
"authentik_core.add_application",
"authentik_core.add_applicationentitlement",
"authentik_core.add_authenticatedsession",
"authentik_core.add_group",
"authentik_core.add_groupsourceconnection",
@ -12542,6 +12672,7 @@
"authentik_core.add_usersourceconnection",
"authentik_core.assign_user_permissions",
"authentik_core.change_application",
"authentik_core.change_applicationentitlement",
"authentik_core.change_authenticatedsession",
"authentik_core.change_group",
"authentik_core.change_groupsourceconnection",
@ -12552,6 +12683,7 @@
"authentik_core.change_user",
"authentik_core.change_usersourceconnection",
"authentik_core.delete_application",
"authentik_core.delete_applicationentitlement",
"authentik_core.delete_authenticatedsession",
"authentik_core.delete_group",
"authentik_core.delete_groupsourceconnection",
@ -12567,6 +12699,7 @@
"authentik_core.reset_user_password",
"authentik_core.unassign_user_permissions",
"authentik_core.view_application",
"authentik_core.view_applicationentitlement",
"authentik_core.view_authenticatedsession",
"authentik_core.view_group",
"authentik_core.view_groupsourceconnection",
@ -13179,6 +13312,52 @@
}
}
},
"model_authentik_core.applicationentitlement": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"title": "Name"
},
"app": {
"type": "integer",
"title": "App"
},
"attributes": {
"type": "object",
"additionalProperties": true,
"title": "Attributes"
}
},
"required": []
},
"model_authentik_core.applicationentitlement_permissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"permission"
],
"properties": {
"permission": {
"type": "string",
"enum": [
"add_applicationentitlement",
"change_applicationentitlement",
"delete_applicationentitlement",
"view_applicationentitlement"
]
},
"user": {
"type": "integer"
},
"role": {
"type": "string"
}
}
}
},
"model_authentik_core.token": {
"type": "object",
"properties": {

View File

@ -42,9 +42,21 @@ entries:
"given_name": request.user.name,
"preferred_username": request.user.username,
"nickname": request.user.username,
# groups is not part of the official userinfo schema, but is a quasi-standard
"groups": [group.name for group in request.user.ak_groups.all()],
}
- identifiers:
managed: goauthentik.io/providers/oauth2/scope-entitlements
model: authentik_providers_oauth2.scopemapping
attrs:
name: "authentik default OAuth Mapping: Application Entitlements"
scope_name: entitlements
description: "Application entitlements"
expression: |
entitlements = [entitlement.name for entitlement in request.user.app_entitlements(provider.application)]
return {
"entitlements": entitlements,
"roles": entitlements,
}
- identifiers:
managed: goauthentik.io/providers/oauth2/scope-offline_access
model: authentik_providers_oauth2.scopemapping

View File

@ -14,6 +14,7 @@ type Claims struct {
Name string `json:"name"`
PreferredUsername string `json:"preferred_username"`
Groups []string `json:"groups"`
Entitlements []string `json:"entitlements"`
Sid string `json:"sid"`
Proxy *ProxyClaims `json:"ak_proxy"`

View File

@ -41,6 +41,7 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) {
// https://goauthentik.io/docs/providers/proxy/proxy
headers.Set("X-authentik-username", c.PreferredUsername)
headers.Set("X-authentik-groups", strings.Join(c.Groups, "|"))
headers.Set("X-authentik-entitlements", strings.Join(c.Entitlements, "|"))
headers.Set("X-authentik-email", c.Email)
headers.Set("X-authentik-name", c.Name)
headers.Set("X-authentik-uid", c.Sub)

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-26 00:09+0000\n"
"POT-Creation-Date: 2024-12-18 13:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1873,6 +1873,10 @@ msgstr ""
msgid "Custom krb5.conf to use. Uses the system one by default"
msgstr ""
#: authentik/sources/kerberos/models.py
msgid "KAdmin server type"
msgstr ""
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
msgstr ""
@ -2812,7 +2816,7 @@ msgstr ""
#, python-format
msgid ""
"\n"
" If you did not request a password change, please ignore this Email. The "
" If you did not request a password change, please ignore this email. The "
"link above is valid for %(expires)s.\n"
" "
msgstr ""
@ -2833,7 +2837,7 @@ msgstr ""
#, python-format
msgid ""
"\n"
"If you did not request a password change, please ignore this Email. The link "
"If you did not request a password change, please ignore this email. The link "
"above is valid for %(expires)s.\n"
msgstr ""
@ -3098,6 +3102,22 @@ msgstr ""
msgid "Passwords don't match."
msgstr ""
#: authentik/stages/redirect/api.py
msgid "Target URL should be present when mode is Static."
msgstr ""
#: authentik/stages/redirect/api.py
msgid "Target Flow should be present when mode is Flow."
msgstr ""
#: authentik/stages/redirect/models.py
msgid "Redirect Stage"
msgstr ""
#: authentik/stages/redirect/models.py
msgid "Redirect Stages"
msgstr ""
#: authentik/stages/user_delete/models.py
msgid "User Delete Stage"
msgstr ""

View File

@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-26 00:09+0000\n"
"POT-Creation-Date: 2024-12-18 13:31+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Marc Schmitt, 2024\n"
"Language-Team: French (https://app.transifex.com/authentik/teams/119923/fr/)\n"
@ -2084,6 +2084,10 @@ msgid "Custom krb5.conf to use. Uses the system one by default"
msgstr ""
"krb5.conf personnalisé à utiliser. Utilise celui du système par défault"
#: authentik/sources/kerberos/models.py
msgid "KAdmin server type"
msgstr "Type de serveur KAdmin"
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
msgstr "Synchroniser les utilisateurs Kerberos dans authentik"
@ -3105,7 +3109,7 @@ msgstr ""
#, python-format
msgid ""
"\n"
" If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
" If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
" "
msgstr ""
"\n"
@ -3129,7 +3133,7 @@ msgstr ""
#, python-format
msgid ""
"\n"
"If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
"If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
msgstr ""
"\n"
"Si vous n'avez pas requis de changement de mot de passe, veuillez ignorer cet e-mail. Le lien ci-dessus est valide pendant %(expires)s.\n"
@ -3434,6 +3438,22 @@ msgstr "Étapes invite"
msgid "Passwords don't match."
msgstr "Les mots de passe ne correspondent pas."
#: authentik/stages/redirect/api.py
msgid "Target URL should be present when mode is Static."
msgstr "L'URL destination doit être présente lorsque le mode est Statique."
#: authentik/stages/redirect/api.py
msgid "Target Flow should be present when mode is Flow."
msgstr "Le flux destination doit être présent lorsque le mode est Flux."
#: authentik/stages/redirect/models.py
msgid "Redirect Stage"
msgstr "Étape de redirection"
#: authentik/stages/redirect/models.py
msgid "Redirect Stages"
msgstr "Étapes de redirection"
#: authentik/stages/user_delete/models.py
msgid "User Delete Stage"
msgstr "Étape de suppression utilisateur"

View File

@ -13,15 +13,16 @@
# albanobattistella <albanobattistella@gmail.com>, 2024
# Nicola Mersi, 2024
# tom max, 2024
# Marc Schmitt, 2024
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-18 00:09+0000\n"
"POT-Creation-Date: 2024-11-26 00:09+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: tom max, 2024\n"
"Last-Translator: Marc Schmitt, 2024\n"
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -89,9 +90,9 @@ msgid "authentik Export - {date}"
msgstr "Esportazione authentik - {date}"
#: authentik/blueprints/v1/tasks.py authentik/crypto/tasks.py
#, python-format
msgid "Successfully imported %(count)d files."
msgstr "Importato con successo %(count)d file."
#, python-brace-format
msgid "Successfully imported {count} files."
msgstr "Importato con successo {count} file."
#: authentik/brands/models.py
msgid ""
@ -635,7 +636,7 @@ msgstr "Fasi Sorgenti"
#: authentik/events/api/tasks.py
#, python-brace-format
msgid "Successfully started task {name}."
msgstr "Attività {nome} avviata correttamente."
msgstr "Attività {name} avviata correttamente."
#: authentik/events/models.py
msgid "Event"
@ -937,14 +938,14 @@ msgid "Starting full provider sync"
msgstr "Avvio della sincronizzazione completa del provider"
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "Sincronizzando pagina %(page)d degli utenti"
#, python-brace-format
msgid "Syncing page {page} of users"
msgstr "Sincronizzando pagina {page} degli utenti"
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "Sincronizzando pagina %(page)d dei gruppi"
#, python-brace-format
msgid "Syncing page {page} of groups"
msgstr "Sincronizzando pagina {page} dei gruppi"
#: authentik/lib/sync/outgoing/tasks.py
#, python-brace-format
@ -1117,10 +1118,10 @@ msgid "Event Matcher Policies"
msgstr "Criteri Corrispondenza Evento"
#: authentik/policies/expiry/models.py
#, python-format
msgid "Password expired %(days)d days ago. Please update your password."
#, python-brace-format
msgid "Password expired {days} days ago. Please update your password."
msgstr ""
"Password scaduta %(days)d giorni fa. Si prega di aggiornare la password."
"Password scaduta {days} giorni fa. Si prega di aggiornare la password."
#: authentik/policies/expiry/models.py
msgid "Password has expired."
@ -1254,9 +1255,9 @@ msgid "Invalid password."
msgstr "Password invalida."
#: authentik/policies/password/models.py
#, python-format
msgid "Password exists on %(count)d online lists."
msgstr "Password esistente in %(count)d lite online."
#, python-brace-format
msgid "Password exists on {count} online lists."
msgstr "Password esistente in {count} lite online."
#: authentik/policies/password/models.py
msgid "Password is too weak."
@ -1383,6 +1384,11 @@ msgstr "Providers LDAP"
msgid "Search full LDAP directory"
msgstr "Ricerca completa nella directory LDAP"
#: authentik/providers/oauth2/api/providers.py
#, python-brace-format
msgid "Invalid Regex Pattern: {url}"
msgstr "Modello Regex non valido: {url}"
#: authentik/providers/oauth2/id_token.py
msgid "Based on the Hashed User ID"
msgstr "Basato sull'ID utente hashato"
@ -1428,6 +1434,14 @@ msgid "Each provider has a different issuer, based on the application slug."
msgstr ""
"Ogni provider ha un issuer differente, basato sullo slug dell'applicazione."
#: authentik/providers/oauth2/models.py
msgid "Strict URL comparison"
msgstr "Confronto URL rigoroso"
#: authentik/providers/oauth2/models.py
msgid "Regular Expression URL matching"
msgstr "Corrispondenza URL espressione regolare"
#: authentik/providers/oauth2/models.py
msgid "code (Authorization Code Flow)"
msgstr "code (Flusso di autorizzazione del codice)"
@ -1508,10 +1522,6 @@ msgstr "Client Secret"
msgid "Redirect URIs"
msgstr "URL di reindirizzamento"
#: authentik/providers/oauth2/models.py
msgid "Enter each URI on a new line."
msgstr "Inserisci ogni URI su una nuova riga."
#: authentik/providers/oauth2/models.py
msgid "Include claims in id_token"
msgstr "Includere le richieste in id_token"

76
poetry.lock generated
View File

@ -408,13 +408,13 @@ typeguard = ">=2.13.3,<5.0.0"
[[package]]
name = "aws-cdk-lib"
version = "2.172.0"
version = "2.173.2"
description = "Version 2 of the AWS Cloud Development Kit library"
optional = false
python-versions = "~=3.8"
files = [
{file = "aws_cdk_lib-2.172.0-py3-none-any.whl", hash = "sha256:960b64af8eb272d2bc80d42dab4748863c2021c39dbc543bb6e7bec0fdafa099"},
{file = "aws_cdk_lib-2.172.0.tar.gz", hash = "sha256:4e8cb368256024e2d35874d7ab2e68812177d7990a27b2ceb50c454e8a018533"},
{file = "aws_cdk_lib-2.173.2-py3-none-any.whl", hash = "sha256:1b76846669de83e6572e9c46f5708f6ac045d8e710bafb044230f24e722601ef"},
{file = "aws_cdk_lib-2.173.2.tar.gz", hash = "sha256:9eb355c4fd5c1aa56317549600baf88dd4d3b520e2081132119b51349ead8c03"},
]
[package.dependencies]
@ -1467,13 +1467,13 @@ django = ">=3"
[[package]]
name = "django-pglock"
version = "1.7.0"
version = "1.7.1"
description = "Postgres locking routines and lock table access."
optional = false
python-versions = "<4,>=3.9.0"
files = [
{file = "django_pglock-1.7.0-py3-none-any.whl", hash = "sha256:4e28fa19cae96f072f3b74a368519442c5413b1ce72f75f816b77dd567d456df"},
{file = "django_pglock-1.7.0.tar.gz", hash = "sha256:180da6d3067b1dcb46b5e37745ee32fe0d8d5976c53bc8912dcf2a46e5000b6a"},
{file = "django_pglock-1.7.1-py3-none-any.whl", hash = "sha256:15db418fb56bee37fc8707038495b5085af9b8c203ebfa300202572127bdb3f0"},
{file = "django_pglock-1.7.1.tar.gz", hash = "sha256:69050bdb522fd34585d49bb8a4798dbfbab9ec4754dd1927b1b9eef2ec0edadf"},
]
[package.dependencies]
@ -1922,13 +1922,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
version = "2.154.0"
version = "2.155.0"
description = "Google API Client Library for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "google_api_python_client-2.154.0-py2.py3-none-any.whl", hash = "sha256:a521bbbb2ec0ba9d6f307cdd64ed6e21eeac372d1bd7493a4ab5022941f784ad"},
{file = "google_api_python_client-2.154.0.tar.gz", hash = "sha256:1b420062e03bfcaa1c79e2e00a612d29a6a934151ceb3d272fe150a656dc8f17"},
{file = "google_api_python_client-2.155.0-py2.py3-none-any.whl", hash = "sha256:83fe9b5aa4160899079d7c93a37be306546a17e6686e2549bcc9584f1a229747"},
{file = "google_api_python_client-2.155.0.tar.gz", hash = "sha256:25529f89f0d13abcf3c05c089c423fb2858ac16e0b3727543393468d0d7af67c"},
]
[package.dependencies]
@ -3463,13 +3463,13 @@ files = [
[[package]]
name = "pdoc"
version = "15.0.0"
version = "15.0.1"
description = "API Documentation for Python Projects"
optional = false
python-versions = ">=3.9"
files = [
{file = "pdoc-15.0.0-py3-none-any.whl", hash = "sha256:151b0187a25eaf827099e981d6dbe3a4f68aeb18d0d637c24edcab788d5540f1"},
{file = "pdoc-15.0.0.tar.gz", hash = "sha256:b761220d3ba129cd87e6da1bb7b62c8e799973ab9c595de7ba1a514850d86da5"},
{file = "pdoc-15.0.1-py3-none-any.whl", hash = "sha256:fd437ab8eb55f9b942226af7865a3801e2fb731665199b74fd9a44737dbe20f9"},
{file = "pdoc-15.0.1.tar.gz", hash = "sha256:3b08382c9d312243ee6c2a1813d0ff517a6ab84d596fa2c6c6b5255b17c3d666"},
]
[package.dependencies]
@ -4630,29 +4630,29 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.8.2"
version = "0.8.3"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"},
{file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"},
{file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"},
{file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"},
{file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"},
{file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"},
{file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"},
{file = "ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6"},
{file = "ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939"},
{file = "ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452"},
{file = "ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd"},
{file = "ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20"},
{file = "ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc"},
{file = "ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060"},
{file = "ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea"},
{file = "ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964"},
{file = "ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9"},
{file = "ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936"},
{file = "ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3"},
]
[[package]]
@ -5087,13 +5087,13 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "9.3.8"
version = "9.4.1"
description = "Twilio API client and TwiML generator"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-9.3.8-py2.py3-none-any.whl", hash = "sha256:fce1f629295285d583dbe1d615f114a77aab25a654ba569bb18d304d31e9ca3b"},
{file = "twilio-9.3.8.tar.gz", hash = "sha256:93a80639db711e58915cfdf772da6274b005ef86f5d2f6092433cb3d53a25303"},
{file = "twilio-9.4.1-py2.py3-none-any.whl", hash = "sha256:2447e041cec11167d7765aaa62ab1dae3b82b712245ca9a966096acd8b9f426f"},
{file = "twilio-9.4.1.tar.gz", hash = "sha256:e24c640696ccc726bba14160951da3cfc6b4bcb772fdcb3e8c16dc3cc851ef12"},
]
[package.dependencies]
@ -5258,13 +5258,13 @@ zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "uvicorn"
version = "0.32.1"
version = "0.34.0"
description = "The lightning-fast ASGI server."
optional = false
python-versions = ">=3.8"
python-versions = ">=3.9"
files = [
{file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"},
{file = "uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175"},
{file = "uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4"},
{file = "uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9"},
]
[package.dependencies]

View File

@ -3097,6 +3097,285 @@ paths:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/application_entitlements/:
get:
operationId: core_application_entitlements_list
description: ApplicationEntitlement Viewset
parameters:
- in: query
name: app
schema:
type: string
format: uuid
- in: query
name: name
schema:
type: string
- name: ordering
required: false
in: query
description: Which field to use when ordering the results.
schema:
type: string
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
- in: query
name: pbm_uuid
schema:
type: string
format: uuid
- name: search
required: false
in: query
description: A search term.
schema:
type: string
tags:
- core
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedApplicationEntitlementList'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
post:
operationId: core_application_entitlements_create
description: ApplicationEntitlement Viewset
tags:
- core
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlementRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlement'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/application_entitlements/{pbm_uuid}/:
get:
operationId: core_application_entitlements_retrieve
description: ApplicationEntitlement Viewset
parameters:
- in: path
name: pbm_uuid
schema:
type: string
format: uuid
description: A UUID string identifying this Application Entitlement.
required: true
tags:
- core
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlement'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
put:
operationId: core_application_entitlements_update
description: ApplicationEntitlement Viewset
parameters:
- in: path
name: pbm_uuid
schema:
type: string
format: uuid
description: A UUID string identifying this Application Entitlement.
required: true
tags:
- core
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlementRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlement'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
patch:
operationId: core_application_entitlements_partial_update
description: ApplicationEntitlement Viewset
parameters:
- in: path
name: pbm_uuid
schema:
type: string
format: uuid
description: A UUID string identifying this Application Entitlement.
required: true
tags:
- core
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedApplicationEntitlementRequest'
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ApplicationEntitlement'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
delete:
operationId: core_application_entitlements_destroy
description: ApplicationEntitlement Viewset
parameters:
- in: path
name: pbm_uuid
schema:
type: string
format: uuid
description: A UUID string identifying this Application Entitlement.
required: true
tags:
- core
security:
- authentik: []
responses:
'204':
description: No response body
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/application_entitlements/{pbm_uuid}/used_by/:
get:
operationId: core_application_entitlements_used_by_list
description: Get a list of all objects that use this object
parameters:
- in: path
name: pbm_uuid
schema:
type: string
format: uuid
description: A UUID string identifying this Application Entitlement.
required: true
tags:
- core
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UsedBy'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/applications/:
get:
operationId: core_applications_list
@ -23305,6 +23584,7 @@ paths:
- authentik_blueprints.blueprintinstance
- authentik_brands.brand
- authentik_core.application
- authentik_core.applicationentitlement
- authentik_core.group
- authentik_core.token
- authentik_core.user
@ -23545,6 +23825,7 @@ paths:
- authentik_blueprints.blueprintinstance
- authentik_brands.brand
- authentik_core.application
- authentik_core.applicationentitlement
- authentik_core.group
- authentik_core.token
- authentik_core.user
@ -25008,6 +25289,12 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupKerberosSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25042,6 +25329,11 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedGroupKerberosSourceConnectionRequest'
security:
- authentik: []
responses:
@ -25196,6 +25488,12 @@ paths:
description: Group-source connection Viewset
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupOAuthSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25263,6 +25561,12 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupOAuthSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25296,6 +25600,11 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedGroupOAuthSourceConnectionRequest'
security:
- authentik: []
responses:
@ -25448,6 +25757,12 @@ paths:
description: Group-source connection Viewset
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupPlexSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25515,6 +25830,12 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupPlexSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25548,6 +25869,11 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedGroupPlexSourceConnectionRequest'
security:
- authentik: []
responses:
@ -25741,6 +26067,12 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroupSAMLSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -25774,6 +26106,11 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedGroupSAMLSourceConnectionRequest'
security:
- authentik: []
responses:
@ -28734,6 +29071,12 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
@ -28767,6 +29110,11 @@ paths:
required: true
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedUserSourceConnectionRequest'
security:
- authentik: []
responses:
@ -38070,6 +38418,38 @@ components:
- pk
- provider_obj
- slug
ApplicationEntitlement:
type: object
description: ApplicationEntitlement Serializer
properties:
pbm_uuid:
type: string
format: uuid
readOnly: true
name:
type: string
app:
type: string
format: uuid
attributes: {}
required:
- app
- name
- pbm_uuid
ApplicationEntitlementRequest:
type: object
description: ApplicationEntitlement Serializer
properties:
name:
type: string
minLength: 1
app:
type: string
format: uuid
attributes: {}
required:
- app
- name
ApplicationRequest:
type: object
description: Application Serializer
@ -42555,14 +42935,15 @@ components:
group:
type: string
format: uuid
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
identifier:
type: string
readOnly: true
created:
type: string
format: date-time
@ -42573,6 +42954,24 @@ components:
- identifier
- pk
- source
- source_obj
GroupKerberosSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- group
- identifier
- source
GroupMatchingModeEnum:
enum:
- identifier
@ -42667,14 +43066,15 @@ components:
group:
type: string
format: uuid
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
identifier:
type: string
readOnly: true
created:
type: string
format: date-time
@ -42685,6 +43085,24 @@ components:
- identifier
- pk
- source
- source_obj
GroupOAuthSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- group
- identifier
- source
GroupPlexSourceConnection:
type: object
description: Plex Group-Source connection Serializer
@ -42696,14 +43114,15 @@ components:
group:
type: string
format: uuid
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
identifier:
type: string
readOnly: true
created:
type: string
format: date-time
@ -42714,6 +43133,24 @@ components:
- identifier
- pk
- source
- source_obj
GroupPlexSourceConnectionRequest:
type: object
description: Plex Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- group
- identifier
- source
GroupRequest:
type: object
description: Group Serializer
@ -42753,14 +43190,15 @@ components:
group:
type: string
format: uuid
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
identifier:
type: string
readOnly: true
created:
type: string
format: date-time
@ -42771,6 +43209,24 @@ components:
- identifier
- pk
- source
- source_obj
GroupSAMLSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- group
- identifier
- source
IdentificationChallenge:
type: object
description: Identification challenges with all UI elements
@ -42801,7 +43257,9 @@ components:
flow_designation:
$ref: '#/components/schemas/FlowDesignationEnum'
captcha_stage:
$ref: '#/components/schemas/CaptchaChallenge'
allOf:
- $ref: '#/components/schemas/CaptchaChallenge'
nullable: true
enroll_url:
type: string
recovery_url:
@ -44732,6 +45190,7 @@ components:
- authentik_core.group
- authentik_core.user
- authentik_core.application
- authentik_core.applicationentitlement
- authentik_core.token
- authentik_enterprise.license
- authentik_providers_google_workspace.googleworkspaceprovider
@ -45812,6 +46271,18 @@ components:
- radius
- rac
type: string
PaginatedApplicationEntitlementList:
type: object
properties:
pagination:
$ref: '#/components/schemas/Pagination'
results:
type: array
items:
$ref: '#/components/schemas/ApplicationEntitlement'
required:
- pagination
- results
PaginatedApplicationList:
type: object
properties:
@ -47714,6 +48185,17 @@ components:
required:
- backends
- name
PatchedApplicationEntitlementRequest:
type: object
description: ApplicationEntitlement Serializer
properties:
name:
type: string
minLength: 1
app:
type: string
format: uuid
attributes: {}
PatchedApplicationRequest:
type: object
description: Application Serializer
@ -48562,6 +49044,45 @@ components:
default_group_email_domain:
type: string
minLength: 1
PatchedGroupKerberosSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
PatchedGroupOAuthSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
PatchedGroupPlexSourceConnectionRequest:
type: object
description: Plex Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
PatchedGroupRequest:
type: object
description: Group Serializer
@ -48588,6 +49109,19 @@ components:
items:
type: string
format: uuid
PatchedGroupSAMLSourceConnectionRequest:
type: object
description: OAuth Group-Source connection Serializer
properties:
group:
type: string
format: uuid
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
PatchedIdentificationStageRequest:
type: object
description: IdentificationStage Serializer
@ -50510,6 +51044,9 @@ components:
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
@ -50562,6 +51099,11 @@ components:
type: object
description: OAuth Source Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
@ -50574,6 +51116,11 @@ components:
type: object
description: Plex Source connection Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
@ -50623,9 +51170,23 @@ components:
type: object
description: SAML Source Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
PatchedUserSourceConnectionRequest:
type: object
description: User source connection
properties:
user:
type: integer
source:
type: string
format: uuid
PatchedUserWriteStageRequest:
type: object
description: UserWriteStage Serializer
@ -55550,6 +56111,9 @@ components:
user:
type: integer
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
@ -55564,6 +56128,7 @@ components:
- identifier
- pk
- source
- source_obj
- user
UserKerberosSourceConnectionRequest:
type: object
@ -55571,11 +56136,15 @@ components:
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- identifier
- source
- user
UserLoginChallenge:
type: object
@ -55798,8 +56367,10 @@ components:
title: ID
user:
type: integer
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
@ -55815,11 +56386,17 @@ components:
- identifier
- pk
- source
- source_obj
- user
UserOAuthSourceConnectionRequest:
type: object
description: OAuth Source Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
@ -55830,6 +56407,8 @@ components:
nullable: true
required:
- identifier
- source
- user
UserObjectPermission:
type: object
description: User-bound object level permission
@ -55887,8 +56466,10 @@ components:
title: ID
user:
type: integer
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
@ -55903,11 +56484,17 @@ components:
- identifier
- pk
- source
- source_obj
- user
UserPlexSourceConnectionRequest:
type: object
description: Plex Source connection Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
@ -55918,6 +56505,8 @@ components:
required:
- identifier
- plex_token
- source
- user
UserRequest:
type: object
description: User Serializer
@ -55969,8 +56558,10 @@ components:
title: ID
user:
type: integer
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
@ -55985,16 +56576,24 @@ components:
- identifier
- pk
- source
- source_obj
- user
UserSAMLSourceConnectionRequest:
type: object
description: SAML Source Serializer
properties:
user:
type: integer
source:
type: string
format: uuid
identifier:
type: string
minLength: 1
required:
- identifier
- source
- user
UserSelf:
type: object
description: User Serializer for information a user can retrieve about themselves
@ -56130,7 +56729,7 @@ components:
- title
UserSourceConnection:
type: object
description: OAuth Source Serializer
description: User source connection
properties:
pk:
type: integer
@ -56138,8 +56737,10 @@ components:
title: ID
user:
type: integer
readOnly: true
source:
type: string
format: uuid
source_obj:
allOf:
- $ref: '#/components/schemas/Source'
readOnly: true
@ -56151,6 +56752,19 @@ components:
- created
- pk
- source
- source_obj
- user
UserSourceConnectionRequest:
type: object
description: User source connection
properties:
user:
type: integer
source:
type: string
format: uuid
required:
- source
- user
UserTypeEnum:
enum:

View File

@ -9,7 +9,7 @@ http://localhost {
uri /outpost.goauthentik.io/auth/caddy
# capitalization of the headers is important, otherwise they will be empty
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
# optional, in this config trust all private ranges, should probably be set to the outposts IP
trusted_proxies private_ranges

View File

@ -23,12 +23,14 @@ server {
# translate headers from the outposts back to the actual upstream
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
auth_request_set $authentik_name $upstream_http_x_authentik_name;
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-entitlements $authentik_entitlements;
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-name $authentik_name;
proxy_set_header X-authentik-uid $authentik_uid;

View File

@ -26,6 +26,7 @@ http:
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-entitlements
- X-authentik-email
- X-authentik-name
- X-authentik-uid

View File

@ -192,5 +192,5 @@ class TestSourceOAuth2(SeleniumTestCase):
results = body_json["results"]
self.assertEqual(len(results), 1)
connection = results[0]
self.assertEqual(connection["source"]["slug"], self.slug)
self.assertEqual(connection["source_obj"]["slug"], self.slug)
self.assertEqual(connection["user"], self.user.pk)

8
web/package-lock.json generated
View File

@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2024.10.5-1734022840",
"@goauthentik/api": "^2024.10.5-1734528783",
"@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",
@ -1775,9 +1775,9 @@
}
},
"node_modules/@goauthentik/api": {
"version": "2024.10.5-1734022840",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.10.5-1734022840.tgz",
"integrity": "sha512-scVh/WyDMPvYkJt1DEZY1EbEWyUGCpISo2PUIQmZgSGF0opMBafwLPMT+LFJIm0hEmGiJ4leyn4BIfKsQKV+mg=="
"version": "2024.10.5-1734528783",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.10.5-1734528783.tgz",
"integrity": "sha512-jYo1hpBcsmyL3r8lnjWX1BVQUtVnwEM9c/TjNyxQX47TEdYEdXnyO037KGJxnGNQS5Dm+gCsKaExI/a18bNZeQ=="
},
"node_modules/@goauthentik/web": {
"resolved": "",

View File

@ -11,7 +11,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2024.10.5-1734022840",
"@goauthentik/api": "^2024.10.5-1734528783",
"@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",

View File

@ -1,6 +1,7 @@
import "@goauthentik/admin/applications/ApplicationAuthorizeChart";
import "@goauthentik/admin/applications/ApplicationCheckAccessForm";
import "@goauthentik/admin/applications/ApplicationForm";
import "@goauthentik/admin/applications/entitlements/ApplicationEntitlementPage";
import "@goauthentik/admin/policies/BoundPoliciesList";
import "@goauthentik/admin/rbac/ObjectPermissionsPage";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
@ -301,6 +302,28 @@ export class ApplicationViewPage extends AKElement {
</div>
</div>
</section>
<section
slot="page-app-entitlements"
data-tab-title="${msg("Application entitlements")}"
>
<div slot="header" class="pf-c-banner pf-m-info">
${msg("Application entitlements are in preview.")}
<a href="mailto:hello+feature/app-ent@goauthentik.io"
>${msg("Send us feedback!")}</a
>
</div>
<div class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__title">
${msg(
"These entitlements can be used to configure user access in this application.",
)}
</div>
<ak-application-entitlements-list .app=${this.application.pk}>
</ak-application-entitlements-list>
</div>
</div>
</section>
<section
slot="page-policy-bindings"
data-tab-title="${msg("Policy / Group / User Bindings")}"

View File

@ -0,0 +1,89 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect";
import YAML from "yaml";
import { msg } from "@lit/localize";
import { CSSResult } from "lit";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import { ApplicationEntitlement, CoreApi } from "@goauthentik/api";
@customElement("ak-application-entitlement-form")
export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement, string> {
async loadInstance(pk: string): Promise<ApplicationEntitlement> {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsRetrieve({
pbmUuid: pk,
});
}
@property()
targetPk?: string;
getSuccessMessage(): string {
if (this.instance?.pbmUuid) {
return msg("Successfully updated entitlement.");
} else {
return msg("Successfully created entitlement.");
}
}
static get styles(): CSSResult[] {
return [...super.styles, PFContent];
}
send(data: ApplicationEntitlement): Promise<unknown> {
if (this.targetPk) {
data.app = this.targetPk;
}
if (this.instance?.pbmUuid) {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsUpdate({
pbmUuid: this.instance.pbmUuid || "",
applicationEntitlementRequest: data,
});
} else {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsCreate({
applicationEntitlementRequest: data,
});
}
}
renderForm(): TemplateResult {
return html` <ak-form-element-horizontal label=${msg("Name")} ?required=${true} name="name">
<input
type="text"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Attributes")}
?required=${false}
name="attributes"
>
<ak-codemirror
mode=${CodeMirrorMode.YAML}
value="${YAML.stringify(first(this.instance?.attributes, {}))}"
>
</ak-codemirror>
<p class="pf-c-form__helper-text">
${msg("Set custom attributes using YAML or JSON.")}
</p>
</ak-form-element-horizontal>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ak-application-entitlement-form": ApplicationEntitlementForm;
}
}

View File

@ -0,0 +1,152 @@
import "@goauthentik/admin/applications/entitlements/ApplicationEntitlementForm";
import "@goauthentik/admin/policies/BoundPoliciesList";
import { PolicyBindingCheckTarget } from "@goauthentik/admin/policies/utils";
import "@goauthentik/admin/rbac/ObjectPermissionModal";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { PFSize } from "@goauthentik/common/enums";
import "@goauthentik/components/ak-status-label";
import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/forms/DeleteBulkForm";
import "@goauthentik/elements/forms/ModalForm";
import "@goauthentik/elements/forms/ProxyForm";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
ApplicationEntitlement,
CoreApi,
RbacPermissionsAssignedByUsersListModelEnum,
} from "@goauthentik/api";
@customElement("ak-application-entitlements-list")
export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
@property()
app?: string;
checkbox = true;
clearOnRefresh = true;
expandable = true;
order = "order";
async apiEndpoint(): Promise<PaginatedResponse<ApplicationEntitlement>> {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsList({
...(await this.defaultEndpointConfig()),
app: this.app || "",
});
}
columns(): TableColumn[] {
return [new TableColumn(msg("Name"), "name"), new TableColumn(msg("Actions"))];
}
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Application entitlement(s)")}
.objects=${this.selectedElements}
.usedBy=${(item: ApplicationEntitlement) => {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsUsedByList({
pbmUuid: item.pbmUuid || "",
});
}}
.delete=${(item: ApplicationEntitlement) => {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsDestroy({
pbmUuid: item.pbmUuid || "",
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
row(item: ApplicationEntitlement): TemplateResult[] {
return [
html`${item.name}`,
html`<ak-forms-modal size=${PFSize.Medium}>
<span slot="submit"> ${msg("Update")} </span>
<span slot="header"> ${msg("Update Entitlement")} </span>
<ak-application-entitlement-form
slot="form"
.instancePk=${item.pbmUuid}
targetPk=${ifDefined(this.app)}
>
</ak-application-entitlement-form>
<button slot="trigger" class="pf-c-button pf-m-plain">
<pf-tooltip position="top" content=${msg("Edit")}>
<i class="fas fa-edit"></i>
</pf-tooltip>
</button>
</ak-forms-modal>
<ak-rbac-object-permission-modal
model=${RbacPermissionsAssignedByUsersListModelEnum.CoreApplicationentitlement}
objectPk=${item.pbmUuid}
>
</ak-rbac-object-permission-modal>`,
];
}
renderExpanded(item: ApplicationEntitlement): TemplateResult {
return html` <td></td>
<td role="cell" colspan="4">
<div class="pf-c-table__expandable-row-content">
<div class="pf-c-content">
<p>
${msg(
"These bindings control which users have access to this entitlement.",
)}
</p>
<ak-bound-policies-list
.target=${item.pbmUuid}
.allowedTypes=${[
PolicyBindingCheckTarget.group,
PolicyBindingCheckTarget.user,
]}
>
</ak-bound-policies-list>
</div>
</div>
</td>`;
}
renderEmpty(): TemplateResult {
return super.renderEmpty(
html`<ak-empty-state
header=${msg("No app entitlements created.")}
icon="pf-icon-module"
>
<div slot="body">
${msg(
"This application does currently not have any application entitlement defined.",
)}
</div>
<div slot="primary"></div>
</ak-empty-state>`,
);
}
renderToolbar(): TemplateResult {
return html`<ak-forms-modal size=${PFSize.Medium}>
<span slot="submit"> ${msg("Create")} </span>
<span slot="header"> ${msg("Create Entitlement")} </span>
<ak-application-entitlement-form slot="form" targetPk=${ifDefined(this.app)}>
</ak-application-entitlement-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${msg("Create entitlement")}
</button>
</ak-forms-modal> `;
}
}
declare global {
interface HTMLElementTagNameMap {
"ak-application-roles-list": ApplicationEntitlementsPage;
}
}

View File

@ -1,6 +1,11 @@
import "@goauthentik/admin/groups/GroupForm";
import "@goauthentik/admin/policies/PolicyBindingForm";
import { PolicyBindingNotice } from "@goauthentik/admin/policies/PolicyBindingForm";
import "@goauthentik/admin/policies/PolicyWizard";
import {
PolicyBindingCheckTarget,
PolicyBindingCheckTargetToLabel,
} from "@goauthentik/admin/policies/utils";
import "@goauthentik/admin/users/UserForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { PFSize } from "@goauthentik/common/enums.js";
@ -13,7 +18,7 @@ import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg, str } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { TemplateResult, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
@ -24,14 +29,25 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
@property()
target?: string;
@property({ type: Boolean })
policyOnly = false;
@property({ type: Array })
allowedTypes: PolicyBindingCheckTarget[] = [
PolicyBindingCheckTarget.group,
PolicyBindingCheckTarget.user,
PolicyBindingCheckTarget.policy,
];
@property({ type: Array })
typeNotices: PolicyBindingNotice[] = [];
checkbox = true;
clearOnRefresh = true;
order = "order";
get allowedTypesLabel(): string {
return this.allowedTypes.map((ct) => PolicyBindingCheckTargetToLabel(ct)).join(" / ");
}
async apiEndpoint(): Promise<PaginatedResponse<PolicyBinding>> {
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsList({
...(await this.defaultEndpointConfig()),
@ -42,7 +58,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
columns(): TableColumn[] {
return [
new TableColumn(msg("Order"), "order"),
new TableColumn(msg("Policy / User / Group")),
new TableColumn(this.allowedTypesLabel),
new TableColumn(msg("Enabled"), "enabled"),
new TableColumn(msg("Timeout"), "timeout"),
new TableColumn(msg("Actions")),
@ -121,7 +137,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
return [
{ key: msg("Order"), value: item.order.toString() },
{
key: msg("Policy / User / Group"),
key: this.allowedTypesLabel,
value: this.getPolicyUserGroupRowLabel(item),
},
];
@ -156,8 +172,9 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
<ak-policy-binding-form
slot="form"
.instancePk=${item.pk}
.allowedTypes=${this.allowedTypes}
.typeNotices=${this.typeNotices}
targetPk=${ifDefined(this.target)}
?policyOnly=${this.policyOnly}
>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
@ -183,7 +200,8 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
<ak-policy-binding-form
slot="form"
targetPk=${ifDefined(this.target)}
?policyOnly=${this.policyOnly}
.allowedTypes=${this.allowedTypes}
.typeNotices=${this.typeNotices}
>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
@ -196,22 +214,25 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
}
renderToolbar(): TemplateResult {
return html`<ak-policy-wizard
createText=${msg("Create and bind Policy")}
?showBindingPage=${true}
bindingTarget=${ifDefined(this.target)}
></ak-policy-wizard>
return html`${this.allowedTypes.includes(PolicyBindingCheckTarget.policy)
? html`<ak-policy-wizard
createText=${msg("Create and bind Policy")}
?showBindingPage=${true}
bindingTarget=${ifDefined(this.target)}
></ak-policy-wizard>`
: nothing}
<ak-forms-modal size=${PFSize.Medium}>
<span slot="submit"> ${msg("Create")} </span>
<span slot="header"> ${msg("Create Binding")} </span>
<ak-policy-binding-form
slot="form"
targetPk=${ifDefined(this.target)}
?policyOnly=${this.policyOnly}
.allowedTypes=${this.allowedTypes}
.typeNotices=${this.typeNotices}
>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${msg("Bind existing policy/group/user")}
${msg(str`Bind existing ${this.allowedTypesLabel}`)}
</button>
</ak-forms-modal> `;
}

View File

@ -1,3 +1,7 @@
import {
PolicyBindingCheckTarget,
PolicyBindingCheckTargetToLabel,
} from "@goauthentik/admin/policies/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first, groupBy } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-toggle-group";
@ -7,7 +11,7 @@ import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect";
import { msg } from "@lit/localize";
import { CSSResult } from "lit";
import { CSSResult, nothing } from "lit";
import { TemplateResult, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
@ -25,11 +29,7 @@ import {
User,
} from "@goauthentik/api";
enum target {
policy = "policy",
group = "group",
user = "user",
}
export type PolicyBindingNotice = { type: PolicyBindingCheckTarget; notice: string };
@customElement("ak-policy-binding-form")
export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
@ -38,13 +38,13 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
policyBindingUuid: pk,
});
if (binding?.policyObj) {
this.policyGroupUser = target.policy;
this.policyGroupUser = PolicyBindingCheckTarget.policy;
}
if (binding?.groupObj) {
this.policyGroupUser = target.group;
this.policyGroupUser = PolicyBindingCheckTarget.group;
}
if (binding?.userObj) {
this.policyGroupUser = target.user;
this.policyGroupUser = PolicyBindingCheckTarget.user;
}
this.defaultOrder = await this.getOrder();
return binding;
@ -54,10 +54,17 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
targetPk?: string;
@state()
policyGroupUser: target = target.policy;
policyGroupUser: PolicyBindingCheckTarget = PolicyBindingCheckTarget.policy;
@property({ type: Boolean })
policyOnly = false;
@property({ type: Array })
allowedTypes: PolicyBindingCheckTarget[] = [
PolicyBindingCheckTarget.group,
PolicyBindingCheckTarget.user,
PolicyBindingCheckTarget.policy,
];
@property({ type: Array })
typeNotices: PolicyBindingNotice[] = [];
@state()
defaultOrder = 0;
@ -74,20 +81,26 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
return [...super.styles, PFContent];
}
async load(): Promise<void> {
// Overwrite the default for policyGroupUser with the first allowed type,
// as this function is called when the correct parameters are set
this.policyGroupUser = this.allowedTypes[0];
}
send(data: PolicyBinding): Promise<unknown> {
if (this.targetPk) {
data.target = this.targetPk;
}
switch (this.policyGroupUser) {
case target.policy:
case PolicyBindingCheckTarget.policy:
data.user = null;
data.group = null;
break;
case target.group:
case PolicyBindingCheckTarget.group:
data.policy = null;
data.user = null;
break;
case target.user:
case PolicyBindingCheckTarget.user:
data.policy = null;
data.group = null;
break;
@ -122,13 +135,18 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
renderModeSelector(): TemplateResult {
return html` <ak-toggle-group
value=${this.policyGroupUser}
@ak-toggle=${(ev: CustomEvent<{ value: target }>) => {
@ak-toggle=${(ev: CustomEvent<{ value: PolicyBindingCheckTarget }>) => {
this.policyGroupUser = ev.detail.value;
}}
>
<option value=${target.policy}>${msg("Policy")}</option>
<option value=${target.group}>${msg("Group")}</option>
<option value=${target.user}>${msg("User")}</option>
${Object.keys(PolicyBindingCheckTarget).map((ct) => {
if (this.allowedTypes.includes(ct as PolicyBindingCheckTarget)) {
return html`<option value=${ct}>
${PolicyBindingCheckTargetToLabel(ct as PolicyBindingCheckTarget)}
</option>`;
}
return nothing;
})}
</ak-toggle-group>`;
}
@ -139,7 +157,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
<ak-form-element-horizontal
label=${msg("Policy")}
name="policy"
?hidden=${this.policyGroupUser !== target.policy}
?hidden=${this.policyGroupUser !== PolicyBindingCheckTarget.policy}
>
<ak-search-select
.groupBy=${(items: Policy[]) => {
@ -169,11 +187,16 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
?blankable=${true}
>
</ak-search-select>
${this.typeNotices
.filter(({ type }) => type === PolicyBindingCheckTarget.policy)
.map((msg) => {
return html`<p class="pf-c-form__helper-text">${msg.notice}</p>`;
})}
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Group")}
name="group"
?hidden=${this.policyGroupUser !== target.group}
?hidden=${this.policyGroupUser !== PolicyBindingCheckTarget.group}
>
<ak-search-select
.fetchObjects=${async (query?: string): Promise<Group[]> => {
@ -201,18 +224,16 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
?blankable=${true}
>
</ak-search-select>
${this.policyOnly
? html`<p class="pf-c-form__helper-text">
${msg(
"Group mappings can only be checked if a user is already logged in when trying to access this source.",
)}
</p>`
: html``}
${this.typeNotices
.filter(({ type }) => type === PolicyBindingCheckTarget.group)
.map((msg) => {
return html`<p class="pf-c-form__helper-text">${msg.notice}</p>`;
})}
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("User")}
name="user"
?hidden=${this.policyGroupUser !== target.user}
?hidden=${this.policyGroupUser !== PolicyBindingCheckTarget.user}
>
<ak-search-select
.fetchObjects=${async (query?: string): Promise<User[]> => {
@ -240,13 +261,11 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
?blankable=${true}
>
</ak-search-select>
${this.policyOnly
? html`<p class="pf-c-form__helper-text">
${msg(
"User mappings can only be checked if a user is already logged in when trying to access this source.",
)}
</p>`
: html``}
${this.typeNotices
.filter(({ type }) => type === PolicyBindingCheckTarget.user)
.map((msg) => {
return html`<p class="pf-c-form__helper-text">${msg.notice}</p>`;
})}
</ak-form-element-horizontal>
</div>
</div>

View File

@ -0,0 +1,18 @@
import { msg } from "@lit/localize";
export enum PolicyBindingCheckTarget {
policy = "policy",
group = "group",
user = "user",
}
export function PolicyBindingCheckTargetToLabel(ct: PolicyBindingCheckTarget): string {
switch (ct) {
case PolicyBindingCheckTarget.group:
return msg("Group");
case PolicyBindingCheckTarget.user:
return msg("User");
case PolicyBindingCheckTarget.policy:
return msg("Policy");
}
}

View File

@ -2,6 +2,7 @@ import "@goauthentik/admin/policies/BoundPoliciesList";
import "@goauthentik/admin/rbac/ObjectPermissionsPage";
import "@goauthentik/admin/sources/oauth/OAuthSourceDiagram";
import "@goauthentik/admin/sources/oauth/OAuthSourceForm";
import { sourceBindingTypeNotices } from "@goauthentik/admin/sources/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import "@goauthentik/components/events/ObjectChangelog";
@ -240,7 +241,10 @@ export class OAuthSourceViewPage extends AKElement {
)}
</div>
<div class="pf-c-card__body">
<ak-bound-policies-list .target=${this.source.pk} ?policyOnly=${true}>
<ak-bound-policies-list
.target=${this.source.pk}
.typeNotices=${sourceBindingTypeNotices()}
>
</ak-bound-policies-list>
</div>
</div>

View File

@ -1,6 +1,7 @@
import "@goauthentik/admin/policies/BoundPoliciesList";
import "@goauthentik/admin/rbac/ObjectPermissionsPage";
import "@goauthentik/admin/sources/plex/PlexSourceForm";
import { sourceBindingTypeNotices } from "@goauthentik/admin/sources/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import "@goauthentik/components/events/ObjectChangelog";
@ -130,7 +131,10 @@ export class PlexSourceViewPage extends AKElement {
)}
</div>
<div class="pf-c-card__body">
<ak-bound-policies-list .target=${this.source.pk} ?policyOnly=${true}>
<ak-bound-policies-list
.target=${this.source.pk}
.typeNotices=${sourceBindingTypeNotices()}
>
</ak-bound-policies-list>
</div>
</div>

View File

@ -1,6 +1,7 @@
import "@goauthentik/admin/policies/BoundPoliciesList";
import "@goauthentik/admin/rbac/ObjectPermissionsPage";
import "@goauthentik/admin/sources/saml/SAMLSourceForm";
import { sourceBindingTypeNotices } from "@goauthentik/admin/sources/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import "@goauthentik/components/events/ObjectChangelog";
@ -207,7 +208,10 @@ export class SAMLSourceViewPage extends AKElement {
)}
</div>
<div class="pf-c-card__body">
<ak-bound-policies-list .target=${this.source.pk} ?policyOnly=${true}>
<ak-bound-policies-list
.target=${this.source.pk}
.typeNotices=${sourceBindingTypeNotices()}
>
</ak-bound-policies-list>
</div>
</div>

View File

@ -1,3 +1,6 @@
import { PolicyBindingCheckTarget } from "@goauthentik/admin/policies/utils";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
export function renderSourceIcon(name: string, iconUrl: string | undefined | null): TemplateResult {
@ -11,3 +14,20 @@ export function renderSourceIcon(name: string, iconUrl: string | undefined | nul
}
return icon;
}
export function sourceBindingTypeNotices() {
return [
{
type: PolicyBindingCheckTarget.group,
notice: msg(
"Group mappings can only be checked if a user is already logged in when trying to access this source.",
),
},
{
type: PolicyBindingCheckTarget.user,
notice: msg(
"User mappings can only be checked if a user is already logged in when trying to access this source.",
),
},
];
}

View File

@ -92,8 +92,8 @@ export class PromptStageForm extends BaseStageForm<PromptStage> {
<ak-dual-select-dynamic-selected
.provider=${policiesProvider}
.selector=${policiesSelector(this.instance?.validationPolicies)}
available-label="${msg("Available Fields")}"
selected-label="${msg("Selected Fields")}"
available-label="${msg("Available Policies")}"
selected-label="${msg("Selected Policies")}"
></ak-dual-select-dynamic-selected>
<p class="pf-c-form__helper-text">
${msg(

View File

@ -70,7 +70,7 @@ export class UserSourceSettingsPage extends AKElement {
let connectionPk = -1;
if (this.connections) {
const connections = this.connections.results.filter(
(con) => con.source.slug === source.objectUid,
(con) => con.sourceObj.slug === source.objectUid,
);
if (connections.length > 0) {
connectionPk = connections[0].pk;

View File

@ -3795,14 +3795,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Immer nach Zustimmung fragen</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Einwilligung gilt unbegrenzt</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Einwilligung erlischt.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
<target>Einwilligung erlischt in</target>
@ -4177,12 +4169,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s7b105164d209f670">
<source>Require authentication</source>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
</trans-unit>
@ -5907,9 +5893,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
@ -7072,6 +7055,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -3974,14 +3974,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Always require consent</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Consent given last indefinitely</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Consent expires.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
<target>Consent expires in</target>
@ -4382,14 +4374,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>Require authentication</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Require no authentication.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Require superuser.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
<target>Required authentication level for this flow.</target>
@ -6171,9 +6155,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
@ -7336,6 +7317,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -3731,14 +3731,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Exigir siempre el consentimiento</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>El último consentimiento otorgado indefinidamente</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>El consentimiento caduca.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
<target>El consentimiento vence en</target>
@ -4108,12 +4100,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s7b105164d209f670">
<source>Require authentication</source>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
</trans-unit>
@ -5825,9 +5811,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
@ -6990,6 +6973,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</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="fr" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -596,9 +596,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>L'URL "
<x id="0" equiv-text="${this.url}"/>" n'a pas été trouvée.</target>
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>L'URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot; n'a pas été trouvée.</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1568,7 +1568,7 @@
</trans-unit>
<trans-unit id="s33ed903c210a6209">
<source>Token to authenticate with. Currently only bearer authentication is supported.</source>
<target>Jeton d'authentification à utiliser. Actuellement, seule l'authentification "bearer authentication" est prise en charge.</target>
<target>Jeton d'authentification à utiliser. Actuellement, seule l'authentification &quot;bearer authentication&quot; est prise en charge.</target>
</trans-unit>
<trans-unit id="sfc8bb104e2c05af8">
@ -1736,8 +1736,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 "fa-test".</source>
<target>Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome "fa-test".</target>
<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>Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome &quot;fa-test&quot;.</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2815,7 +2815,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s33683c3b1dbaf264">
<source>To use SSL instead, use 'ldaps://' and disable this option.</source>
<target>Pour utiliser SSL à la base, utilisez "ldaps://" et désactviez cette option.</target>
<target>Pour utiliser SSL à la base, utilisez &quot;ldaps://&quot; et désactviez cette option.</target>
</trans-unit>
<trans-unit id="s2221fef80f4753a2">
@ -2899,8 +2899,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 "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>Champ qui contient les membres d'un groupe. Si vous utilisez le champ "memberUid", la valeur est censée contenir un nom distinctif relatif, par exemple 'memberUid=un-utilisateur' au lieu de 'memberUid=cn=un-utilisateur,ou=groups,...'</target>
<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>Champ qui contient les membres d'un groupe. Si vous utilisez le champ &quot;memberUid&quot;, la valeur est censée contenir un nom distinctif relatif, par exemple 'memberUid=un-utilisateur' au lieu de 'memberUid=cn=un-utilisateur,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3195,7 +3195,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3198c384c2f68b08">
<source>Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually.</source>
<target>Moment où les utilisateurs temporaires doivent être supprimés. Cela ne s'applique que si votre IDP utilise le format NameID "transient" et que l'utilisateur ne se déconnecte pas manuellement.</target>
<target>Moment où les utilisateurs temporaires doivent être supprimés. Cela ne s'applique que si votre IDP utilise le format NameID &quot;transient&quot; et que l'utilisateur ne se déconnecte pas manuellement.</target>
</trans-unit>
<trans-unit id="sb32e9c1faa0b8673">
@ -3337,7 +3337,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s9f8aac89fe318acc">
<source>Optionally set the 'FriendlyName' value of the Assertion attribute.</source>
<target>Indiquer la valeur "FriendlyName" de l'attribut d'assertion (optionnel)</target>
<target>Indiquer la valeur &quot;FriendlyName&quot; de l'attribut d'assertion (optionnel)</target>
</trans-unit>
<trans-unit id="s851c108679653d2a">
@ -3646,8 +3646,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 "minutes=5".</source>
<target>En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à "minutes=5".</target>
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à &quot;minutes=5&quot;.</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -3823,10 +3823,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}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<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>
<target>Êtes-vous sûr de vouloir mettre à jour
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>"?</target>
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -4902,8 +4902,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A "roaming" authenticator, like a YubiKey</source>
<target>Un authentificateur "itinérant", comme une YubiKey</target>
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<target>Un authentificateur &quot;itinérant&quot;, comme une YubiKey</target>
</trans-unit>
<trans-unit id="sfffba7b23d8fb40c">
@ -4965,16 +4965,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Toujours exiger l'approbation</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>L'approbation dure indéfiniment</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>L'approbation expire.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5228,7 +5218,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s5170f9ef331949c0">
<source>Show arbitrary input fields to the user, for example during enrollment. Data is saved in the flow context under the 'prompt_data' variable.</source>
<target>Afficher des champs de saisie arbitraires à l'utilisateur, par exemple pendant l'inscription. Les données sont enregistrées dans le contexte du flux sous la variable "prompt_data".</target>
<target>Afficher des champs de saisie arbitraires à l'utilisateur, par exemple pendant l'inscription. Les données sont enregistrées dans le contexte du flux sous la variable &quot;prompt_data&quot;.</target>
</trans-unit>
<trans-unit id="s36cb242ac90353bc">
@ -5281,8 +5271,8 @@ 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 "stay signed in", which will extend their session by the time specified here.</source>
<target>Si défini à une durée supérieure à 0, l'utilisateur aura la possibilité de choisir de "rester connecté", ce qui prolongera sa session jusqu'à la durée spécifiée ici.</target>
<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>
<target>Si défini à une durée supérieure à 0, l'utilisateur aura la possibilité de choisir de &quot;rester connecté&quot;, ce qui prolongera sa session jusqu'à la durée spécifiée ici.</target>
</trans-unit>
<trans-unit id="s542a71bb8f41e057">
@ -5476,16 +5466,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>Requiert une authentification</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Requiert l'absence d'authentification</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Requiert un super-utilisateur</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -6050,7 +6030,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="sa7fcf026bd25f231">
<source>Can be in the format of 'unix://' when connecting to a local docker daemon, using 'ssh://' to connect via SSH, or 'https://:2376' when connecting to a remote system.</source>
<target>Peut être au format "unix://" pour une connexion à un service docker local, "ssh://" pour une connexion via SSH, ou "https://:2376" pour une connexion à un système distant.</target>
<target>Peut être au format &quot;unix://&quot; pour une connexion à un service docker local, &quot;ssh://&quot; pour une connexion via SSH, ou &quot;https://:2376&quot; pour une connexion à un système distant.</target>
</trans-unit>
<trans-unit id="saf1d289e3137c2ea">
@ -7302,7 +7282,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="sff0ac1ace2d90709">
<source>Use this provider with nginx's auth_request or traefik's forwardAuth. Each application/domain needs its own provider. Additionally, on each domain, /outpost.goauthentik.io must be routed to the outpost (when using a managed outpost, this is done for you).</source>
<target>Utilisez ce fournisseur avec l'option "auth_request" de Nginx ou "forwardAuth" de Traefik. Chaque application/domaine a besoin de son propre fournisseur. De plus, sur chaque domaine, "/outpost.goauthentik.io" doit être routé vers le poste avancé (lorsque vous utilisez un poste avancé géré, cela est fait pour vous).</target>
<target>Utilisez ce fournisseur avec l'option &quot;auth_request&quot; de Nginx ou &quot;forwardAuth&quot; de Traefik. Chaque application/domaine a besoin de son propre fournisseur. De plus, sur chaque domaine, &quot;/outpost.goauthentik.io&quot; doit être routé vers le poste avancé (lorsque vous utilisez un poste avancé géré, cela est fait pour vous).</target>
</trans-unit>
<trans-unit id="scb58b8a60cad8762">
<source>Default relay state</source>
@ -7692,7 +7672,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<target>Utilisateur créé et ajouté au groupe <x id="0" equiv-text="${this.group.name}"/> avec succès</target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<target>Cet utilisateur sera ajouté au groupe &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;.</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -7763,10 +7743,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<source>Event volume</source>
<target>Volume d'événements</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Forcer l'utilisation d'un avant-poste (le flux ne pourrait être exécuter que depuis un outpost).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Paramètres de connexion.</target>
@ -9042,7 +9018,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<target>Synchroniser le groupe</target>
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${p.name}"/> ("<x id="1" equiv-text="${p.fieldKey}"/>", of type <x id="2" equiv-text="${p.type}"/>)</source>
<source><x id="0" equiv-text="${p.name}"/> (&quot;<x id="1" equiv-text="${p.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${p.type}"/>)</source>
<target><x id="0" equiv-text="${p.name}"/> (&amp;quot;<x id="1" equiv-text="${p.fieldKey}"/>&amp;quot;, de type <x id="2" equiv-text="${p.type}"/>)</target>
</trans-unit>
<trans-unit id="sa38c5a2731be3a46">
@ -9294,8 +9270,8 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<target>URLs de redirection autorisées après un flux d'autorisation réussi. Indiquez également toute origine ici pour les flux implicites.</target>
</trans-unit>
<trans-unit id="s4c49d27de60a532b">
<source>To allow any redirect URI, set the mode to Regex and the value to ".*". Be aware of the possible security implications this can have.</source>
<target>Pour permettre n'importe quelle URI de redirection, définissez cette valeur sur ".*". Soyez conscient des possibles implications de sécurité que cela peut avoir.</target>
<source>To allow any redirect URI, set the mode to Regex and the value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>Pour permettre n'importe quelle URI de redirection, définissez cette valeur sur &quot;.*&quot;. Soyez conscient des possibles implications de sécurité que cela peut avoir.</target>
</trans-unit>
<trans-unit id="s43f899a86c6a3484">
<source>Redirect URIs/Origins</source>
@ -9320,7 +9296,91 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
<target>Les JWTs signés par les fournisseurs sélectionnés peuvent être utilisés pour s'authentifier auprès de ce fournisseur.</target>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
<target>Type KAdmin</target>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
<target>MIT krb5 kadmin</target>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
<target>Heimdal kadmin</target>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
<target>Autre</target>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
<target>Autre type de kadmin</target>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
<target>Pour laisser les utilisateurs réinitialiser leur mot de passe, configurez un flux de récupération sur la marque actuelle.</target>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
<target>L'approbation donnée dure indéfiniment</target>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
<target>L'approbation expire</target>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
<target>Politiques disponibles</target>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
<target>Politiques sélectionnées</target>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
<target>Rediriger l'utilisateur vers un autre flux, éventuellement avec le contexte</target>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
<target>Statique</target>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
<target>URL destination</target>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
<target>Rediriger l'utilisateur vers une URL statique.</target>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
<target>Flux destination</target>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
<target>Rediriger l'utilisateur vers un flux.</target>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
<target>Conserver le contexte du flux</target>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
<target>Requiert l'absence d'authentification</target>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
<target>Requiert un super-utilisateur</target>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
<target>Requiert d'être redirigé depuis un autre flux</target>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
<target>Forcer l'utilisation d'un avant-poste (le flux ne pourrait être exécuter que depuis un avant-poste)</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -4963,16 +4963,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Richiedi sempre il consenso</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Consenso dato l'ultimo indefinitamente</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Consenso scade.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5474,16 +5464,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>Richiedere l'autenticazione</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Richiedere nessuna autenticazione.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Richiedi superutente.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7711,10 +7691,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Event volume</source>
<target>Volume degli eventi</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Richiedere un avamposto (il flusso può essere eseguito solo da un avamposto).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Impostazioni connessione.</target>
@ -9265,6 +9241,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4948,16 +4948,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>항상 동의 요청</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>비한정으로 동의 지속</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>동의가 만료됩니다.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5458,16 +5448,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>인증 필요</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>인증 필요 없음.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>슈퍼유저권한이 필요합니다.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7733,10 +7713,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Event volume</source>
<target>이력 규모</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Outpost필요 (플로우는 Outpost에서만 실행할 수 있음).</target>
</trans-unit>
<trans-unit id="s31f1afc1bfe1cb3a">
<source>Learn more</source>
</trans-unit>
@ -8899,6 +8875,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4934,16 +4934,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Always require consent</source>
<target>Vereis altijd toestemming</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Toestemming blijft onbeperkt geldig</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Toestemming verloopt.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5443,16 +5433,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Require authentication</source>
<target>Vereis authenticatie</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Vereis geen authenticatie.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Vereis supergebruiker.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7678,9 +7658,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s01794c0ee3629c1b">
<source>Flow Info</source>
</trans-unit>
@ -8747,6 +8724,69 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4969,16 +4969,6 @@ Można tu używać tylko zasad, ponieważ dostęp jest sprawdzany przed uwierzyt
<source>Always require consent</source>
<target>Zawsze wymagaj zgody</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Zgoda udzielona na czas nieokreślony</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Zgoda wygasa.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5480,16 +5470,6 @@ w toku, tworzony jest nowy użytkownik i zapisywane są do niego dane.</target>
<source>Require authentication</source>
<target>Wymagaj uwierzytelnienia</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Nie wymagaj uwierzytelnienia.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Wymagaj superużytkownika.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7767,10 +7747,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<source>Event volume</source>
<target>Wolumen zdarzeń</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Wymagaj placówki (przepływ można wykonać tylko z placówki).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Ustawienia połączenia.</target>
@ -9162,6 +9138,69 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4936,16 +4936,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Àĺŵàŷś ŕēǫũĩŕē ćōńśēńţ</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Ćōńśēńţ ĝĩvēń ĺàśţ ĩńďēƒĩńĩţēĺŷ</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Ćōńśēńţ ēxƥĩŕēś.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5446,16 +5436,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>Ŕēǫũĩŕē àũţĥēńţĩćàţĩōń</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Ŕēǫũĩŕē ńō àũţĥēńţĩćàţĩōń.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Ŕēǫũĩŕē śũƥēŕũśēŕ.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7711,10 +7691,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Event volume</source>
<target>Ēvēńţ vōĺũḿē</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Ŕēǫũĩŕē Ōũţƥōśţ (ƒĺōŵ ćàń ōńĺŷ ƀē ēxēćũţēď ƒŕōḿ àń ōũţƥōśţ).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Ćōńńēćţĩōń śēţţĩńĝś.</target>
@ -9202,4 +9178,67 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body></file></xliff>

View File

@ -4968,16 +4968,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>Всегда требовать согласие</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Согласие действует бессрочно</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Согласие истекает.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5479,16 +5469,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>Требуется аутентификация</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Не требуется аутентификация.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Требуется суперпользователь.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7766,10 +7746,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Event volume</source>
<target>Объем событий</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Требовать внешний компонент (поток может быть выполнен только с аванпоста).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Настройки подключения</target>
@ -9225,6 +9201,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4936,16 +4936,6 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
<source>Always require consent</source>
<target>Her zaman rıza gerektirir</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Süresiz olarak verilen izin</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Onayın süresi doluyor.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5446,16 +5436,6 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
<source>Require authentication</source>
<target>Kimlik doğrulaması gerektir</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Kimlik doğrulaması gerektirmez.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Süper kullanıcı gerektirir.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7716,10 +7696,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
<source>Event volume</source>
<target>Olay hacmi</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>gözcü gerektir (akış yalnızca bir gözcüden yürütülebilir).</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>Bağlantı ayarları'nı tıklayın.</target>
@ -9255,6 +9231,69 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -3611,12 +3611,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s26513c9dd154f041">
<source>Always require consent</source>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
</trans-unit>
@ -3969,15 +3963,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s7b105164d209f670">
<source>Require authentication</source>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
</trans-unit>
@ -5923,6 +5908,69 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>
</xliff>

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">
@ -596,9 +596,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">
@ -1737,8 +1737,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">
@ -2901,8 +2901,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">
@ -3648,8 +3648,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">
@ -3825,10 +3825,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">
@ -4904,7 +4904,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>
@ -4967,16 +4967,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>始终需要征得同意授权</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>无限期同意授权</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>同意授权会过期。</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5283,7 +5273,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>
@ -5478,16 +5468,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>需要身份验证</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>需要无身份验证。</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>需要管理员用户。</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7694,7 +7674,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>成功创建用户并添加到组 <x id="0" equiv-text="${this.group.name}"/></target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>此用户将会被添加到组 &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;。</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -7765,10 +7745,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Event volume</source>
<target>事件容量</target>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>需要前哨(流程只能从前哨执行)。</target>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
<target>连接设置。</target>
@ -9044,7 +9020,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>同步组</target>
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${p.name}"/> (&quot;<x id="1" equiv-text="${p.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${p.type}"/>)</source>
<source><x id="0" equiv-text="${p.name}"/> ("<x id="1" equiv-text="${p.fieldKey}"/>", of type <x id="2" equiv-text="${p.type}"/>)</source>
<target><x id="0" equiv-text="${p.name}"/>&amp;quot;<x id="1" equiv-text="${p.fieldKey}"/>&amp;quot;,类型为 <x id="2" equiv-text="${p.type}"/></target>
</trans-unit>
<trans-unit id="sa38c5a2731be3a46">
@ -9296,8 +9272,8 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>授权流程成功后有效的重定向 URI。还可以在此处为隐式流程指定任何来源。</target>
</trans-unit>
<trans-unit id="s4c49d27de60a532b">
<source>To allow any redirect URI, set the mode to Regex and the 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 the mode to Regex and the value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请设置模式为正则表达式并将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s43f899a86c6a3484">
<source>Redirect URIs/Origins</source>
@ -9322,7 +9298,70 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
<target>由已选提供程序签发的 JWT 可以用于此提供程序的身份验证。</target>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -3763,14 +3763,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>始终需要征得同意</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>无限期地给予同意</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>同意过期。</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
<target>同意到期时间</target>
@ -4142,12 +4134,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s7b105164d209f670">
<source>Require authentication</source>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
</trans-unit>
@ -5866,9 +5852,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
@ -7031,6 +7014,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -4926,16 +4926,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Always require consent</source>
<target>總是需要取得同意</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>給予永久性的同意</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>給予有期限的同意</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
@ -5435,16 +5425,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Require authentication</source>
<target>需要身分認證</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>需要無身分認證</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>需要超級使用者</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
@ -7695,9 +7675,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
@ -8860,6 +8837,69 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4f8a3f7792e6b940">
<source>JWTs signed by the selected providers can be used to authenticate to this provider.</source>
</trans-unit>
<trans-unit id="s3cc2b33d2a8000d3">
<source>KAdmin type</source>
</trans-unit>
<trans-unit id="s624e1c8739507529">
<source>MIT krb5 kadmin</source>
</trans-unit>
<trans-unit id="s6d225d9e74dfff6f">
<source>Heimdal kadmin</source>
</trans-unit>
<trans-unit id="sc9e494c8346b7cb5">
<source>Other</source>
</trans-unit>
<trans-unit id="sbf6c78047e8ec8f8">
<source>Other type of kadmin</source>
</trans-unit>
<trans-unit id="sb53d0b77abef2316">
<source>To let a user directly reset their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s2e5226fcf269689b">
<source>Consent given lasts indefinitely</source>
</trans-unit>
<trans-unit id="s7eff620292ed9349">
<source>Consent expires</source>
</trans-unit>
<trans-unit id="s1cc032bcc50b2942">
<source>Available Policies</source>
</trans-unit>
<trans-unit id="s3ad64193ad5f4a5e">
<source>Selected Policies</source>
</trans-unit>
<trans-unit id="sc487e11d5987dbb4">
<source>Redirect the user to another flow, potentially with all gathered context</source>
</trans-unit>
<trans-unit id="sad9d5481474d4f5b">
<source>Static</source>
</trans-unit>
<trans-unit id="se87a96950464bc89">
<source>Target URL</source>
</trans-unit>
<trans-unit id="s7f3097955b19736a">
<source>Redirect the user to a static URL.</source>
</trans-unit>
<trans-unit id="s9bdee1c5130c8240">
<source>Target Flow</source>
</trans-unit>
<trans-unit id="sa5d1405b8d6529c7">
<source>Redirect the user to a Flow.</source>
</trans-unit>
<trans-unit id="s7c9db337d14d42b3">
<source>Keep flow context</source>
</trans-unit>
<trans-unit id="s0d7dea184036a74d">
<source>Require no authentication</source>
</trans-unit>
<trans-unit id="s66f533986ba6182c">
<source>Require superuser</source>
</trans-unit>
<trans-unit id="s26c0a8789930b5fd">
<source>Require being redirected from another flow</source>
</trans-unit>
<trans-unit id="sbfaee8cfbf4e44e8">
<source>Require Outpost (flow can only be executed from an outpost)</source>
</trans-unit>
</body>
</file>

View File

@ -63,7 +63,7 @@ return request.context["oauth_jwt"]["iss"] == "https://my.issuer"
To allow federation between providers, modify the provider settings of the application (whose token will be used for authentication) to select the provider of the application to which you want to federate.
With this configure, any JWT issued by the configured providers can be used to authenticate:
With this configuration, any JWT issued by the configured providers can be used to authenticate:
```
POST /application/o/token/ HTTP/1.1

View File

@ -48,6 +48,16 @@ sequenceDiagram
rp->>user: User is logged in
```
| Endpoint | URL |
| -------------------- | -------------------------------------------------------------------- |
| Authorization | `/application/o/authorize/` |
| Token | `/application/o/token/` |
| User Info | `/application/o/userinfo/` |
| Token Revoke | `/application/o/revoke/` |
| End Session | `/application/o/<application slug>/end-session/` |
| JWKS | `/application/o/<application slug>/jwks/` |
| OpenID Configuration | `/application/o/<application slug>/.well-known/openid-configuration` |
### Additional configuration options with Redirect URIs
When using an OAuth 2.0 provider in authentik, the OP must validate the provided redirect URI by the RP. An authentik admin can configure a list in the **Redirect URI** field on the Provider.
@ -122,16 +132,6 @@ Starting with authentik 2024.2, the refresh token grant type requires the `offli
Scopes can be configured using scope mappings, a type of [property mapping](../property-mappings/index.md#scope-mappings).
| Endpoint | URL |
| -------------------- | -------------------------------------------------------------------- |
| Authorization | `/application/o/authorize/` |
| Token | `/application/o/token/` |
| User Info | `/application/o/userinfo/` |
| Token Revoke | `/application/o/revoke/` |
| End Session | `/application/o/<application slug>/end-session/` |
| JWKS | `/application/o/<application slug>/jwks/` |
| OpenID Configuration | `/application/o/<application slug>/.well-known/openid-configuration` |
## Scope authorization
By default, every user that has access to an application can request any of the configured scopes. Starting with authentik 2022.4, you can do additional checks for the scope in an expression policy (bound to the application):
@ -143,7 +143,23 @@ if "my-admin-scope" in request.context["oauth_scopes"]:
return True
```
## Special scopes
## Default & special scopes
When a client does not request any scopes, authentik will treat the request as if all configured scopes were requested. Depending on the configured authorization flow, consent still needs to be given, and all scopes are listed there.
This does _not_ apply to special scopes, as those are not configurable in the provider.
### Default
- `openid`: A scope required by the OpenID Connect spec to specify that an OAuth interaction is OpenID Connect. Does not add any data to the token.
- `profile`: Include basic profile information, such as username, name and group membership.
- `email`: Include the users' email address.
- `entitlements`: Include application entitlement data.
- `offline_access`: An OAuth 2.0 scope which indicates that the application is requesting a refresh token.
### authentik
- `goauthentik.io/api`: This scope grants the refresh token access to the authentik API on behalf of the user
### GitHub compatibility
@ -152,19 +168,9 @@ return True
- `user:email`: Allows read-only access to `/user`, including email address
- `read:org`: Allows read-only access to `/user/teams`, listing all the user's groups as teams.
### authentik
- `goauthentik.io/api`: This scope grants the refresh token access to the authentik API on behalf of the user
## Default scopes <span class="badge badge--version">authentik 2022.7+</span>
When a client does not request any scopes, authentik will treat the request as if all configured scopes were requested. Depending on the configured authorization flow, consent still needs to be given, and all scopes are listed there.
This does _not_ apply to special scopes, as those are not configurable in the provider.
## Signing & Encryption
[JWT](https://jwt.io/introduction)s created by authentik will always be signed.
[JWTs](https://jwt.io/introduction) created by authentik will always be signed.
When a _Signing Key_ is selected in the provider, the JWT will be signed asymmetrically with the private key of the selected certificate, and can be verified using the public key of the certificate. The public key data of the signing key can be retrieved via the JWKS endpoint listed on the provider page.

View File

@ -12,7 +12,7 @@ app.company {
uri /outpost.goauthentik.io/auth/caddy
# capitalization of the headers is important, otherwise they will be empty
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
# optional, in this config trust all private ranges, should probably be set to the outposts IP
trusted_proxies private_ranges

View File

@ -40,7 +40,7 @@ metadata:
nginx.ingress.kubernetes.io/auth-signin: |-
https://app.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri
nginx.ingress.kubernetes.io/auth-response-headers: |-
Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-entitlements,X-authentik-email,X-authentik-name,X-authentik-uid
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Forwarded-Host $http_host;
```

View File

@ -26,12 +26,14 @@ location / {
# translate headers from the outposts back to the actual upstream
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
auth_request_set $authentik_name $upstream_http_x_authentik_name;
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-entitlements $authentik_entitlements;
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-name $authentik_name;
proxy_set_header X-authentik-uid $authentik_uid;

View File

@ -39,12 +39,14 @@ server {
# translate headers from the outposts back to the actual upstream
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
auth_request_set $authentik_name $upstream_http_x_authentik_name;
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-entitlements $authentik_entitlements;
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-name $authentik_name;
proxy_set_header X-authentik-uid $authentik_uid;

View File

@ -32,7 +32,7 @@ services:
# `authentik-proxy` refers to the service name in the compose file.
traefik.http.middlewares.authentik.forwardauth.address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-entitlements,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
restart: unless-stopped
whoami:

View File

@ -13,6 +13,7 @@ spec:
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-entitlements
- X-authentik-email
- X-authentik-name
- X-authentik-uid

View File

@ -8,6 +8,7 @@ http:
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-entitlements
- X-authentik-email
- X-authentik-name
- X-authentik-uid

View File

@ -36,6 +36,12 @@ Example value: `foo|bar|baz`
The groups the user is member of, separated by a pipe
### `X-authentik-entitlements`
Example value: `foo|bar|baz`
The entitlements on the application this user has access to, separated by a pipe
### `X-authentik-email`
Example value: `root@localhost`

View File

@ -16,7 +16,8 @@ For VS Code, for example, add these entries to your `settings.json`:
"!If sequence",
"!Index scalar",
"!KeyOf scalar",
"!Value scalar"
"!Value scalar",
"!AtIndex scalar"
]
}
```
@ -299,3 +300,23 @@ The above example will resolve to something like this:
- "bar: (index: 1, letter: a)"
- "bar: (index: 2, letter: r)"
```
#### `!AtIndex` <span class="badge badge--version">authentik 2024.12+</span>
Minimal example:
```yaml
value_in_sequence: !AtIndex [["first", "second"], 0] # Resolves to "first"
value_in_mapping: !AtIndex [{ "foo": "bar", "other": "value" }, "foo"] # Resolves to "bar"
```
Example with default value:
```yaml
default_value: !AtIndex [["first"], 100, "default"] # Resolves to "default"
default_value: !AtIndex [["first"], 100] # Throws an error
```
Resolves to the value at a specific index in a sequence or a mapping.
If no value can be found at the specified index and no default is provided, an error is raised and the blueprint is invalid.

View File

@ -65,4 +65,4 @@ In addition to the configuration options above, the following [System settings](
Container images can be pulled from the following URLs:
- ghcr.io/goauthentik/server (https://ghcr.io)
- beryju/authentik (https://index.docker.io)
- authentik/server (https://index.docker.io)

View File

@ -0,0 +1,134 @@
---
title: Release 2024.12
slug: "/releases/2024.12"
---
:::::note
2024.12 has not been released yet! We're publishing these release notes as a preview of what's to come, and for our awesome beta testers trying out release candidates.
To try out the release candidate, replace your Docker image tag with the latest release candidate number, such as 2024.12.0-rc1. You can find the latest one in [the latest releases on GitHub](https://github.com/goauthentik/authentik/releases). If you don't find any, it means we haven't released one yet.
:::::
## Highlights
- **Redirect stage** Conditionally redirect users to other flows and URLs.
- **Application entitlements** <span class="badge badge--info">Preview</span> Additional granular permission configuration on an application-level basis.
- **CloudFormation** <span class="badge badge--info">Preview</span> One-click deploy on AWS.
- **Policies in the application wizard** Configure access restriction while creating an application.
<!-- ## Breaking changes -->
## Breaking changes
- **Impersonation now requires providing a reason**
You can disable this behavior in the **Admin interface** under **System** > **Settings**.
## New features
- **Redirect stage**
This new stage allows redirecting a user to another flow or external URL. This allows for dynamically choosing which flow runs depending on user attributes or other factors, or redirection to another URL.
- **Application entitlements** <span class="badge badge--info">Preview</span>
Centrally configure permissions by granting entitlements to groups and users on an application-level basis.
- **Policies in the application wizard**
In the application creation wizard, administrators can now configure policies bindings along with the other application settings.
- **CloudFormation** <span class="badge badge--info">Preview</span>
Deploy authentik in your own AWS environment with one click using our new [AWS CloudFormation template](../../install-config/install/aws/index.md).
- **OAuth2 provider federation**
Configure [OAuth2 provider federation](../../add-secure-apps/providers/oauth2/client_credentials.md#authentik-issued-jwts-authentik-202412) to allow exchanging authentication tokens between multiple providers.
- **Silent authorization flow**
When authorization flows don't require user interaction, authentik redirects the user directly back to the application, improving user experience.
## Upgrading
This release does not introduce any new requirements. You can follow the upgrade instructions below; for more detailed information about upgrading authentik, refer to our [Upgrade documentation](../../install-config/upgrade.mdx).
:::warning
When you upgrade, be aware that the version of the authentik instance and of any outposts must be the same. We recommended that you always upgrade any outposts at the same time you upgrade your authentik instance.
:::
### Docker Compose
To upgrade, download the new docker-compose file and update the Docker stack with the new version, using these commands:
```shell
wget -O docker-compose.yml https://goauthentik.io/version/2024.12/docker-compose.yml
docker compose up -d
```
The `-O` flag retains the downloaded file's name, overwriting any existing local file with the same name.
### Kubernetes
Upgrade the Helm Chart to the new version, using the following commands:
```shell
helm repo update
helm upgrade authentik authentik/authentik -f values.yaml --version ^2024.12
```
## Minor changes/fixes
- blueprints: add default Password policy (#11793)
- core: add `None` check to a device's `extra_description` (#11904)
- core: add ability to provide reason for impersonation (#11951)
- core: add support to set policy bindings in transactional endpoint (#10399)
- core: fix source_flow_manager throwing error when authenticated user attempts to re-authenticate with existing link (#12080)
- core: use versioned_script for path only (#12003)
- crypto: validate that generated certificate's name is unique (#12015)
- enterprise/rac: fix API Schema for invalidation_flow (#11907)
- internal: add CSP header to files in `/media` (#12092)
- providers/ldap: fix global search_full_directory permission not being sufficient (#12028)
- providers/oauth2: Add provider federation between OAuth2 Providers (#12083)
- providers/oauth2: allow m2m for JWKS without alg in keys (#12196)
- providers/oauth2: fix manual device code entry (#12017)
- providers/oauth2: fix migration (#12138)
- providers/oauth2: fix migration dependencies (#12123)
- providers/oauth2: fix redirect uri input (#12122)
- providers/oauth2: fix size limited index for tokens (#11879)
- providers/proxy: fix Issuer when AUTHENTIK_HOST_BROWSER is set (#11968)
- providers/proxy: fix redirect_uri (#12121)
- providers/scim: accept string and int for SCIM IDs (#12093)
- rbac: fix incorrect object_description for object-level permissions (#12029)
- root: check remote IP for proxy protocol same as HTTP/etc (#12094)
- root: fix activation of locale not being scoped (#12091)
- root: fix database ssl options not set correctly (#12180)
- root: fix health status code (#12255)
- root: fix override locale only if it is not empty (#12283)
- root: support running authentik in subpath (#8675)
- scripts: remove read_replicas from generated dev config (#12078)
- security: fix CVE 2024 52287 (#12114)
- security: fix CVE 2024 52289 (#12113)
- security: fix CVE 2024 52307 (#12115)
- sources/kerberos: add kiprop to ignored system principals (#11852)
- sources/kerberos: use new python-kadmin implementation (#11932)
- stages/captcha: Run interactive captcha in Frame (#11857)
- stages/password: use recovery flow from brand (#11953)
- web/admin: auto-prefill user path for new users based on selected path (#12070)
- web/admin: better footer links (#12004)
- web/admin: bugfix: dual select initialization revision (#12051)
- web/admin: fix brand title not respected in application list (#12068)
- web/admin: fix code-based MFA toggle not working in wizard (#11854)
- web/admin: provide default invalidation flows for LDAP and Radius (#11861)
- web/flows: fix invisible captcha call (#12048)
- web: add italian locale (#11958)
- web: bump cookie, swagger-client and express in /web (#11966)
- web: fix bug that prevented error reporting in current wizard. (#12033)
- web: fix missing status code on failed build (#11903)
- web: simplify `?inline` handler for Storybook (#12246)
- web: update tests for Chromedriver 131 (#12199)
## API Changes
<!-- _Insert output of `make gen-diff` here_ -->

View File

@ -70,15 +70,19 @@ data "authentik_flow" "default-provider-authorization-implicit-consent" {
slug = "default-provider-authorization-implicit-consent"
}
data "authentik_scope_mapping" "scope-email" {
data "authentik_flow" "default-provider-invalidation" {
slug = "default-invalidation-flow"
}
data "authentik_property_mapping_provider_scope" "scope-email" {
name = "authentik default OAuth Mapping: OpenID 'email'"
}
data "authentik_scope_mapping" "scope-profile" {
data "authentik_property_mapping_provider_scope" "scope-profile" {
name = "authentik default OAuth Mapping: OpenID 'profile'"
}
data "authentik_scope_mapping" "scope-openid" {
data "authentik_property_mapping_provider_scope" "scope-openid" {
name = "authentik default OAuth Mapping: OpenID 'openid'"
}
@ -91,11 +95,18 @@ resource "authentik_provider_oauth2" "argocd" {
# Optional: will be generated if not provided
# client_secret = "my_client_secret"
authorization_flow = data.authentik_flow.default-provider-authorization-implicit-consent.id
authorization_flow = data.authentik_flow.default-provider-authorization-implicit_consent.id
invalidation_flow = data.authentik_flow.default-provider-invalidation.id
redirect_uris = [
"https://argocd.company/api/dex/callback",
"http://localhost:8085/auth/callback"
allowed_redirect_uris = [
{
matching_mode = "strict",
url = "https://argocd.company/api/dex/callback",
},
{
matching_mode = "strict",
url = "http://localhost:8085/auth/callback",
}
]
property_mappings = [
@ -115,7 +126,6 @@ resource "authentik_group" "argocd_admins" {
name = "ArgoCD Admins"
}
resource "authentik_group" "argocd_viewers" {
name = "ArgoCD Viewers"
}

View File

@ -18,8 +18,8 @@
"@mdx-js/react": "^3.1.0",
"clsx": "^2.1.1",
"disqus-react": "^1.1.5",
"docusaurus-plugin-openapi-docs": "^4.3.0",
"docusaurus-theme-openapi-docs": "^4.3.0",
"docusaurus-plugin-openapi-docs": "^4.3.1",
"docusaurus-theme-openapi-docs": "^4.3.1",
"postcss": "^8.4.49",
"prism-react-renderer": "^2.4.1",
"react": "^18.3.1",
@ -35,7 +35,7 @@
"@docusaurus/tsconfig": "^3.6.3",
"@docusaurus/types": "^3.3.2",
"@types/react": "^18.3.13",
"aws-cdk": "^2.173.1",
"aws-cdk": "^2.173.2",
"cross-env": "^7.0.3",
"prettier": "3.4.2",
"typescript": "~5.7.2",
@ -6121,9 +6121,9 @@
}
},
"node_modules/aws-cdk": {
"version": "2.173.1",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.173.1.tgz",
"integrity": "sha512-1KWz6ZPPpBk3LyxE+iR4Gi1bbdY5N6Zj7kx/26jqvavBfZle93vT3M0jlTKI6v/bBtpYsVHTOmPFcq0fg1DfCw==",
"version": "2.173.2",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.173.2.tgz",
"integrity": "sha512-qyMU4FoRJdZDUpsOBqyRBALBjf5A2N/MaHKX9iJUkbTET+d+nR07x3ai4TcEES+8pqPFHMTKpQMRDXs9Py/15w==",
"dev": true,
"bin": {
"cdk": "bin/cdk"
@ -8843,10 +8843,9 @@
}
},
"node_modules/docusaurus-plugin-openapi-docs": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-4.3.0.tgz",
"integrity": "sha512-IOxJzLfH8vhGvzQSd9TI99w2naD705r838gaa1/oDlmcaajXYtKePkk7YwcqjLLKgJ/roQcvQAK2qNX/sijQvQ==",
"license": "MIT",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-4.3.1.tgz",
"integrity": "sha512-uVv/mipiQzgqHIhgnTmJmsBW3UuuAufmuyXeHzQR8PGovsjMOKJU6YVDTd8qHlkXQ09IdoBLKG0RUZ9daNxt0w==",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^11.5.4",
"@redocly/openapi-core": "^1.10.5",
@ -9062,10 +9061,9 @@
}
},
"node_modules/docusaurus-theme-openapi-docs": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-4.3.0.tgz",
"integrity": "sha512-tfuvnPiTy+HvKYHR+s0651W5rotHlAZtNVfI/6rl3OYmIw9v2abO9bcUt86JGvmLKYlSKNCtJIotLTY801j/TA==",
"license": "MIT",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-4.3.1.tgz",
"integrity": "sha512-AeMBDckf+L3CDybLuzxUnjfBOa4zvpfux+u8g2apMSRub1Zh17EdqSWapzHWcMRw3xmknR4kqMFboWLXhwW1ew==",
"dependencies": {
"@hookform/error-message": "^2.0.1",
"@reduxjs/toolkit": "^1.7.1",

View File

@ -27,8 +27,8 @@
"@mdx-js/react": "^3.1.0",
"clsx": "^2.1.1",
"disqus-react": "^1.1.5",
"docusaurus-plugin-openapi-docs": "^4.3.0",
"docusaurus-theme-openapi-docs": "^4.3.0",
"docusaurus-plugin-openapi-docs": "^4.3.1",
"docusaurus-theme-openapi-docs": "^4.3.1",
"postcss": "^8.4.49",
"prism-react-renderer": "^2.4.1",
"react": "^18.3.1",
@ -56,7 +56,7 @@
"@docusaurus/tsconfig": "^3.6.3",
"@docusaurus/types": "^3.3.2",
"@types/react": "^18.3.13",
"aws-cdk": "^2.173.1",
"aws-cdk": "^2.173.2",
"cross-env": "^7.0.3",
"prettier": "3.4.2",
"typescript": "~5.7.2",

View File

@ -2,13 +2,14 @@ import { generateVersionDropdown } from "./src/utils.js";
import apiReference from "./docs/developer-docs/api/reference/sidebar";
const releases = [
"releases/2024/v2024.12",
"releases/2024/v2024.10",
"releases/2024/v2024.8",
"releases/2024/v2024.6",
{
type: "category",
label: "Previous versions",
items: [
"releases/2024/v2024.6",
"releases/2024/v2024.4",
"releases/2024/v2024.2",
"releases/2023/v2023.10",