From 116ac30c7275aa9e97cea8d96bf91a788146f3cc Mon Sep 17 00:00:00 2001 From: Jens L Date: Thu, 4 Jan 2024 16:18:12 +0100 Subject: [PATCH] enterprise/providers/rac: add alert that enterprise is required for RAC (#8057) add alert that enterprise is required for RAC Signed-off-by: Jens Langhammer --- authentik/core/api/propertymappings.py | 2 + authentik/core/api/providers.py | 2 + authentik/core/api/utils.py | 3 +- authentik/enterprise/api.py | 14 ++++ authentik/enterprise/apps.py | 6 +- .../enterprise/providers/rac/api/endpoints.py | 3 +- .../providers/rac/api/property_mappings.py | 3 +- .../enterprise/providers/rac/api/providers.py | 3 +- authentik/enterprise/providers/rac/apps.py | 4 +- authentik/enterprise/providers/rac/models.py | 2 +- schema.yml | 4 ++ .../PropertyMappingWizard.ts | 32 +++++++-- web/src/admin/providers/ProviderWizard.ts | 37 +++++++--- .../enterprise/EnterpriseStatusBanner.ts | 6 +- web/xliff/de.xlf | 6 ++ web/xliff/en.xlf | 6 ++ web/xliff/es.xlf | 6 ++ web/xliff/fr.xlf | 72 ++++++++++--------- web/xliff/pl.xlf | 6 ++ web/xliff/pseudo-LOCALE.xlf | 6 ++ web/xliff/tr.xlf | 6 ++ web/xliff/zh-Hans.xlf | 54 +++++++------- web/xliff/zh-Hant.xlf | 6 ++ web/xliff/zh_TW.xlf | 6 ++ 24 files changed, 211 insertions(+), 84 deletions(-) diff --git a/authentik/core/api/propertymappings.py b/authentik/core/api/propertymappings.py index 1e7436be9..d0fa7267b 100644 --- a/authentik/core/api/propertymappings.py +++ b/authentik/core/api/propertymappings.py @@ -19,6 +19,7 @@ from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import MetaNameSerializer, PassiveSerializer, TypeCreateSerializer from authentik.core.expression.evaluator import PropertyMappingEvaluator from authentik.core.models import PropertyMapping +from authentik.enterprise.apps import EnterpriseConfig from authentik.events.utils import sanitize_item from authentik.lib.utils.reflection import all_subclasses from authentik.policies.api.exec import PolicyTestSerializer @@ -95,6 +96,7 @@ class PropertyMappingViewSet( "description": subclass.__doc__, "component": subclass().component, "model_name": subclass._meta.model_name, + "requires_enterprise": isinstance(subclass._meta.app_config, EnterpriseConfig), } ) return Response(TypeCreateSerializer(data, many=True).data) diff --git a/authentik/core/api/providers.py b/authentik/core/api/providers.py index a5095dcde..6c0f4db06 100644 --- a/authentik/core/api/providers.py +++ b/authentik/core/api/providers.py @@ -16,6 +16,7 @@ from rest_framework.viewsets import GenericViewSet from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer from authentik.core.models import Provider +from authentik.enterprise.apps import EnterpriseConfig from authentik.lib.utils.reflection import all_subclasses @@ -113,6 +114,7 @@ class ProviderViewSet( "description": subclass.__doc__, "component": subclass().component, "model_name": subclass._meta.model_name, + "requires_enterprise": isinstance(subclass._meta.app_config, EnterpriseConfig), } ) data.append( diff --git a/authentik/core/api/utils.py b/authentik/core/api/utils.py index c7a188f5c..c79fec22e 100644 --- a/authentik/core/api/utils.py +++ b/authentik/core/api/utils.py @@ -5,7 +5,7 @@ from django.db.models import Model from drf_spectacular.extensions import OpenApiSerializerFieldExtension from drf_spectacular.plumbing import build_basic_type from drf_spectacular.types import OpenApiTypes -from rest_framework.fields import CharField, IntegerField, JSONField +from rest_framework.fields import BooleanField, CharField, IntegerField, JSONField from rest_framework.serializers import Serializer, SerializerMethodField, ValidationError @@ -74,6 +74,7 @@ class TypeCreateSerializer(PassiveSerializer): description = CharField(required=True) component = CharField(required=True) model_name = CharField(required=True) + requires_enterprise = BooleanField(default=False) class CacheSerializer(PassiveSerializer): diff --git a/authentik/enterprise/api.py b/authentik/enterprise/api.py index fdf0a11fc..c13e34b6d 100644 --- a/authentik/enterprise/api.py +++ b/authentik/enterprise/api.py @@ -2,9 +2,11 @@ from datetime import datetime, timedelta from django.utils.timezone import now +from django.utils.translation import gettext as _ from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import extend_schema, inline_serializer from rest_framework.decorators import action +from rest_framework.exceptions import ValidationError from rest_framework.fields import BooleanField, CharField, DateTimeField, IntegerField from rest_framework.permissions import IsAuthenticated from rest_framework.request import Request @@ -20,6 +22,18 @@ from authentik.enterprise.models import License, LicenseKey from authentik.root.install_id import get_install_id +class EnterpriseRequiredMixin: + """Mixin to validate that a valid enterprise license + exists before allowing to safe the object""" + + def validate(self, attrs: dict) -> dict: + """Check that a valid license exists""" + total = LicenseKey.get_total() + if not total.is_valid(): + raise ValidationError(_("Enterprise is required to create/update this object.")) + return super().validate(attrs) + + class LicenseSerializer(ModelSerializer): """License Serializer""" diff --git a/authentik/enterprise/apps.py b/authentik/enterprise/apps.py index 2d918da17..a0b9bed6d 100644 --- a/authentik/enterprise/apps.py +++ b/authentik/enterprise/apps.py @@ -2,7 +2,11 @@ from authentik.blueprints.apps import ManagedAppConfig -class AuthentikEnterpriseConfig(ManagedAppConfig): +class EnterpriseConfig(ManagedAppConfig): + """Base app config for all enterprise apps""" + + +class AuthentikEnterpriseConfig(EnterpriseConfig): """Enterprise app config""" name = "authentik.enterprise" diff --git a/authentik/enterprise/providers/rac/api/endpoints.py b/authentik/enterprise/providers/rac/api/endpoints.py index b0b0239c5..e1c6c5dd8 100644 --- a/authentik/enterprise/providers/rac/api/endpoints.py +++ b/authentik/enterprise/providers/rac/api/endpoints.py @@ -15,6 +15,7 @@ from structlog.stdlib import get_logger from authentik.core.api.used_by import UsedByMixin from authentik.core.models import Provider +from authentik.enterprise.api import EnterpriseRequiredMixin from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer from authentik.enterprise.providers.rac.models import Endpoint from authentik.policies.engine import PolicyEngine @@ -28,7 +29,7 @@ def user_endpoint_cache_key(user_pk: str) -> str: return f"goauthentik.io/providers/rac/endpoint_access/{user_pk}" -class EndpointSerializer(ModelSerializer): +class EndpointSerializer(EnterpriseRequiredMixin, ModelSerializer): """Endpoint Serializer""" provider_obj = RACProviderSerializer(source="provider", read_only=True) diff --git a/authentik/enterprise/providers/rac/api/property_mappings.py b/authentik/enterprise/providers/rac/api/property_mappings.py index 35daec95c..4afef68bb 100644 --- a/authentik/enterprise/providers/rac/api/property_mappings.py +++ b/authentik/enterprise/providers/rac/api/property_mappings.py @@ -5,10 +5,11 @@ from rest_framework.viewsets import ModelViewSet from authentik.core.api.propertymappings import PropertyMappingSerializer from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import JSONDictField +from authentik.enterprise.api import EnterpriseRequiredMixin from authentik.enterprise.providers.rac.models import RACPropertyMapping -class RACPropertyMappingSerializer(PropertyMappingSerializer): +class RACPropertyMappingSerializer(EnterpriseRequiredMixin, PropertyMappingSerializer): """RACPropertyMapping Serializer""" static_settings = JSONDictField() diff --git a/authentik/enterprise/providers/rac/api/providers.py b/authentik/enterprise/providers/rac/api/providers.py index 6dd4f9f82..cda6c2af3 100644 --- a/authentik/enterprise/providers/rac/api/providers.py +++ b/authentik/enterprise/providers/rac/api/providers.py @@ -4,10 +4,11 @@ from rest_framework.viewsets import ModelViewSet from authentik.core.api.providers import ProviderSerializer from authentik.core.api.used_by import UsedByMixin +from authentik.enterprise.api import EnterpriseRequiredMixin from authentik.enterprise.providers.rac.models import RACProvider -class RACProviderSerializer(ProviderSerializer): +class RACProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer): """RACProvider Serializer""" outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all") diff --git a/authentik/enterprise/providers/rac/apps.py b/authentik/enterprise/providers/rac/apps.py index 973159bb9..13930faae 100644 --- a/authentik/enterprise/providers/rac/apps.py +++ b/authentik/enterprise/providers/rac/apps.py @@ -1,8 +1,8 @@ """RAC app config""" -from authentik.blueprints.apps import ManagedAppConfig +from authentik.enterprise.apps import EnterpriseConfig -class AuthentikEnterpriseProviderRAC(ManagedAppConfig): +class AuthentikEnterpriseProviderRAC(EnterpriseConfig): """authentik enterprise rac app config""" name = "authentik.enterprise.providers.rac" diff --git a/authentik/enterprise/providers/rac/models.py b/authentik/enterprise/providers/rac/models.py index d79bbd54c..f2806f32b 100644 --- a/authentik/enterprise/providers/rac/models.py +++ b/authentik/enterprise/providers/rac/models.py @@ -35,7 +35,7 @@ class AuthenticationMode(models.TextChoices): class RACProvider(Provider): - """Remotely access computers/servers""" + """Remotely access computers/servers via RDP/SSH/VNC.""" settings = models.JSONField(default=dict) auth_mode = models.TextField( diff --git a/schema.yml b/schema.yml index 0ea6e8ee0..09b351707 100644 --- a/schema.yml +++ b/schema.yml @@ -19158,6 +19158,7 @@ paths: - tr - tt - udm + - ug - uk - ur - uz @@ -42957,6 +42958,9 @@ components: type: string model_name: type: string + requires_enterprise: + type: boolean + default: false required: - component - description diff --git a/web/src/admin/property-mappings/PropertyMappingWizard.ts b/web/src/admin/property-mappings/PropertyMappingWizard.ts index 4773dd93a..4f0ab6122 100644 --- a/web/src/admin/property-mappings/PropertyMappingWizard.ts +++ b/web/src/admin/property-mappings/PropertyMappingWizard.ts @@ -13,21 +13,24 @@ import { WizardPage } from "@goauthentik/elements/wizard/WizardPage"; import { msg, str } from "@lit/localize"; import { customElement } from "@lit/reactive-element/decorators/custom-element.js"; -import { CSSResult, TemplateResult, html } from "lit"; -import { property } from "lit/decorators.js"; +import { CSSResult, TemplateResult, html, nothing } from "lit"; +import { property, state } from "lit/decorators.js"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFForm from "@patternfly/patternfly/components/Form/form.css"; import PFRadio from "@patternfly/patternfly/components/Radio/radio.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; -import { PropertymappingsApi, TypeCreate } from "@goauthentik/api"; +import { EnterpriseApi, LicenseSummary, PropertymappingsApi, TypeCreate } from "@goauthentik/api"; @customElement("ak-property-mapping-wizard-initial") export class InitialPropertyMappingWizardPage extends WizardPage { @property({ attribute: false }) mappingTypes: TypeCreate[] = []; + @property({ attribute: false }) + enterprise?: LicenseSummary; + static get styles(): CSSResult[] { return [PFBase, PFForm, PFButton, PFRadio]; } @@ -60,11 +63,20 @@ export class InitialPropertyMappingWizardPage extends WizardPage { ]; this.host.isValid = true; }} + ?disabled=${type.requiresEnterprise ? !this.enterprise?.hasLicense : false} /> ${type.description} + ${type.requiresEnterprise && !this.enterprise?.hasLicense + ? html` + + ${msg("Provider require enterprise.")} + ${msg("Learn more")} + + ` + : nothing} `; })} `; @@ -80,10 +92,16 @@ export class PropertyMappingWizard extends AKElement { @property({ attribute: false }) mappingTypes: TypeCreate[] = []; - firstUpdated(): void { - new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllTypesList().then((types) => { - this.mappingTypes = types; - }); + @state() + enterprise?: LicenseSummary; + + async firstUpdated(): Promise { + this.mappingTypes = await new PropertymappingsApi( + DEFAULT_CONFIG, + ).propertymappingsAllTypesList(); + this.enterprise = await new EnterpriseApi( + DEFAULT_CONFIG, + ).enterpriseLicenseSummaryRetrieve(); } render(): TemplateResult { diff --git a/web/src/admin/providers/ProviderWizard.ts b/web/src/admin/providers/ProviderWizard.ts index a65945354..7f19b4d02 100644 --- a/web/src/admin/providers/ProviderWizard.ts +++ b/web/src/admin/providers/ProviderWizard.ts @@ -4,6 +4,7 @@ import "@goauthentik/admin/providers/proxy/ProxyProviderForm"; import "@goauthentik/admin/providers/saml/SAMLProviderForm"; import "@goauthentik/admin/providers/saml/SAMLProviderImportForm"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; +import "@goauthentik/elements/Alert"; import { AKElement } from "@goauthentik/elements/Base"; import "@goauthentik/elements/forms/ProxyForm"; import { paramURL } from "@goauthentik/elements/router/RouterOutlet"; @@ -13,8 +14,8 @@ import { WizardPage } from "@goauthentik/elements/wizard/WizardPage"; import { msg, str } from "@lit/localize"; import { customElement } from "@lit/reactive-element/decorators/custom-element.js"; -import { CSSResult, TemplateResult, html } from "lit"; -import { property } from "lit/decorators.js"; +import { CSSResult, TemplateResult, html, nothing } from "lit"; +import { property, state } from "lit/decorators.js"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFForm from "@patternfly/patternfly/components/Form/form.css"; @@ -22,13 +23,16 @@ import PFHint from "@patternfly/patternfly/components/Hint/hint.css"; import PFRadio from "@patternfly/patternfly/components/Radio/radio.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; -import { ProvidersApi, TypeCreate } from "@goauthentik/api"; +import { EnterpriseApi, LicenseSummary, ProvidersApi, TypeCreate } from "@goauthentik/api"; @customElement("ak-provider-wizard-initial") export class InitialProviderWizardPage extends WizardPage { @property({ attribute: false }) providerTypes: TypeCreate[] = []; + @property({ attribute: false }) + enterprise?: LicenseSummary; + static get styles(): CSSResult[] { return [PFBase, PFForm, PFHint, PFButton, PFRadio]; } @@ -79,9 +83,18 @@ export class InitialProviderWizardPage extends WizardPage { this.host.steps = ["initial", `type-${type.component}`]; this.host.isValid = true; }} + ?disabled=${type.requiresEnterprise ? !this.enterprise?.hasLicense : false} /> ${type.description} + ${type.requiresEnterprise && !this.enterprise?.hasLicense + ? html` + + ${msg("Provider require enterprise.")} + ${msg("Learn more")} + + ` + : nothing} `; })} `; @@ -100,15 +113,19 @@ export class ProviderWizard extends AKElement { @property({ attribute: false }) providerTypes: TypeCreate[] = []; + @state() + enterprise?: LicenseSummary; + @property({ attribute: false }) finalHandler: () => Promise = () => { return Promise.resolve(); }; - firstUpdated(): void { - new ProvidersApi(DEFAULT_CONFIG).providersAllTypesList().then((types) => { - this.providerTypes = types; - }); + async firstUpdated(): Promise { + this.providerTypes = await new ProvidersApi(DEFAULT_CONFIG).providersAllTypesList(); + this.enterprise = await new EnterpriseApi( + DEFAULT_CONFIG, + ).enterpriseLicenseSummaryRetrieve(); } render(): TemplateResult { @@ -121,7 +138,11 @@ export class ProviderWizard extends AKElement { return this.finalHandler(); }} > - + ${this.providerTypes.map((type) => { return html` diff --git a/web/src/elements/enterprise/EnterpriseStatusBanner.ts b/web/src/elements/enterprise/EnterpriseStatusBanner.ts index 0ac115457..09d376759 100644 --- a/web/src/elements/enterprise/EnterpriseStatusBanner.ts +++ b/web/src/elements/enterprise/EnterpriseStatusBanner.ts @@ -21,10 +21,8 @@ export class EnterpriseStatusBanner extends AKElement { return [PFBanner]; } - firstUpdated(): void { - new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseSummaryRetrieve().then((b) => { - this.summary = b; - }); + async firstUpdated(): Promise { + this.summary = await new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseSummaryRetrieve(); } renderBanner(): TemplateResult { diff --git a/web/xliff/de.xlf b/web/xliff/de.xlf index 8cac9d9de..403d08256 100644 --- a/web/xliff/de.xlf +++ b/web/xliff/de.xlf @@ -6237,6 +6237,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/en.xlf b/web/xliff/en.xlf index aa28b7c6a..a8c3a759b 100644 --- a/web/xliff/en.xlf +++ b/web/xliff/en.xlf @@ -6513,6 +6513,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/es.xlf b/web/xliff/es.xlf index cbe16ba84..ece851727 100644 --- a/web/xliff/es.xlf +++ b/web/xliff/es.xlf @@ -6153,6 +6153,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/fr.xlf b/web/xliff/fr.xlf index 407618e65..3bac1b49b 100644 --- a/web/xliff/fr.xlf +++ b/web/xliff/fr.xlf @@ -1,4 +1,4 @@ - + @@ -613,9 +613,9 @@ Il y a jour(s) - The URL "" was not found. - L'URL " - " n'a pas été trouvée. + The URL "" was not found. + L'URL " + " n'a pas été trouvée. @@ -1057,8 +1057,8 @@ Il y a jour(s) - To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. - 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. + To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. + 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. @@ -1630,7 +1630,7 @@ Il y a jour(s) Token to authenticate with. Currently only bearer authentication is supported. - Jeton d'authentification à utiliser. Actuellement, seule l'authentification "bearer authentication" est prise en charge. + Jeton d'authentification à utiliser. Actuellement, seule l'authentification "bearer authentication" est prise en charge. @@ -1798,8 +1798,8 @@ Il y a jour(s) - Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". - Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome "fa-test". + Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". + Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome "fa-test". @@ -2892,7 +2892,7 @@ doesn't pass when either or both of the selected options are equal or above the To use SSL instead, use 'ldaps://' and disable this option. - Pour utiliser SSL à la base, utilisez "ldaps://" et désactviez cette option. + Pour utiliser SSL à la base, utilisez "ldaps://" et désactviez cette option. @@ -2981,8 +2981,8 @@ doesn't pass when either or both of the selected options are equal or above the - 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,...' - 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,...' + 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,...' + 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,...' @@ -3277,7 +3277,7 @@ doesn't pass when either or both of the selected options are equal or above the 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. - 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. + 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. @@ -3445,7 +3445,7 @@ doesn't pass when either or both of the selected options are equal or above the Optionally set the 'FriendlyName' value of the Assertion attribute. - Indiquer la valeur "FriendlyName" de l'attribut d'assertion (optionnel) + Indiquer la valeur "FriendlyName" de l'attribut d'assertion (optionnel) @@ -3774,8 +3774,8 @@ doesn't pass when either or both of the selected options are equal or above the - When using an external logging solution for archiving, this can be set to "minutes=5". - En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à "minutes=5". + When using an external logging solution for archiving, this can be set to "minutes=5". + En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à "minutes=5". @@ -3784,8 +3784,8 @@ doesn't pass when either or both of the selected options are equal or above the - Format: "weeks=3;days=2;hours=3,seconds=2". - Format : "weeks=3;days=2;hours=3,seconds=2". + Format: "weeks=3;days=2;hours=3,seconds=2". + Format : "weeks=3;days=2;hours=3,seconds=2". @@ -3981,10 +3981,10 @@ doesn't pass when either or both of the selected options are equal or above the - Are you sure you want to update ""? + Are you sure you want to update ""? Êtes-vous sûr de vouloir mettre à jour - " - " ? + " + " ? @@ -5070,8 +5070,8 @@ doesn't pass when either or both of the selected options are equal or above the - A "roaming" authenticator, like a YubiKey - Un authentificateur "itinérant", comme une YubiKey + A "roaming" authenticator, like a YubiKey + Un authentificateur "itinérant", comme une YubiKey @@ -5396,7 +5396,7 @@ doesn't pass when either or both of the selected options are equal or above the Show arbitrary input fields to the user, for example during enrollment. Data is saved in the flow context under the 'prompt_data' variable. - 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". + 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". @@ -5405,10 +5405,10 @@ doesn't pass when either or both of the selected options are equal or above the - ("", of type ) + ("", of type ) - (" - ", de type + (" + ", de type ) @@ -5457,8 +5457,8 @@ doesn't pass when either or both of the selected options are equal or above the - 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. - 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. + 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. + 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. @@ -6242,7 +6242,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti 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. - 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. + 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. @@ -7549,7 +7549,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti 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). - 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). + 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). Default relay state @@ -7963,7 +7963,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti Utilisateur créé et ajouté au groupe avec succès - This user will be added to the group "". + This user will be added to the group "". Cet utilisateur sera ajouté au groupe "". @@ -8201,7 +8201,13 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti Determines how long a session lasts before being disconnected and requiring re-authorization. Détermine combien de temps une session dure avant déconnexion et ré-authorisation. + + + Provider require enterprise. + + + Learn more - \ No newline at end of file + diff --git a/web/xliff/pl.xlf b/web/xliff/pl.xlf index b52ea863c..a0e16c3be 100644 --- a/web/xliff/pl.xlf +++ b/web/xliff/pl.xlf @@ -6361,6 +6361,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/pseudo-LOCALE.xlf b/web/xliff/pseudo-LOCALE.xlf index bc883faa7..217082220 100644 --- a/web/xliff/pseudo-LOCALE.xlf +++ b/web/xliff/pseudo-LOCALE.xlf @@ -8099,4 +8099,10 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + Provider require enterprise. + + + Learn more + diff --git a/web/xliff/tr.xlf b/web/xliff/tr.xlf index 7b03127c0..f2cd5d161 100644 --- a/web/xliff/tr.xlf +++ b/web/xliff/tr.xlf @@ -6146,6 +6146,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/zh-Hans.xlf b/web/xliff/zh-Hans.xlf index 1ef89db75..d1572b445 100644 --- a/web/xliff/zh-Hans.xlf +++ b/web/xliff/zh-Hans.xlf @@ -1,4 +1,4 @@ - + @@ -613,9 +613,9 @@ - The URL "" was not found. - 未找到 URL " - "。 + The URL "" was not found. + 未找到 URL " + "。 @@ -1057,8 +1057,8 @@ - To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. - 要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。 + To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. + 要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。 @@ -1799,8 +1799,8 @@ - Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". - 输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。 + Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". + 输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。 @@ -2983,8 +2983,8 @@ doesn't pass when either or both of the selected options are equal or above the - 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,...' - 包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...' + 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,...' + 包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...' @@ -3776,8 +3776,8 @@ doesn't pass when either or both of the selected options are equal or above the - When using an external logging solution for archiving, this can be set to "minutes=5". - 使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。 + When using an external logging solution for archiving, this can be set to "minutes=5". + 使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。 @@ -3786,8 +3786,8 @@ doesn't pass when either or both of the selected options are equal or above the - Format: "weeks=3;days=2;hours=3,seconds=2". - 格式:"weeks=3;days=2;hours=3,seconds=2"。 + Format: "weeks=3;days=2;hours=3,seconds=2". + 格式:"weeks=3;days=2;hours=3,seconds=2"。 @@ -3983,10 +3983,10 @@ doesn't pass when either or both of the selected options are equal or above the - Are you sure you want to update ""? + Are you sure you want to update ""? 您确定要更新 - " - " 吗? + " + " 吗? @@ -5072,7 +5072,7 @@ doesn't pass when either or both of the selected options are equal or above the - A "roaming" authenticator, like a YubiKey + A "roaming" authenticator, like a YubiKey 像 YubiKey 这样的“漫游”身份验证器 @@ -5407,10 +5407,10 @@ doesn't pass when either or both of the selected options are equal or above the - ("", of type ) + ("", of type ) - (" - ",类型为 + (" + ",类型为 @@ -5459,7 +5459,7 @@ doesn't pass when either or both of the selected options are equal or above the - 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. + 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. 如果设置时长大于 0,用户可以选择“保持登录”选项,这将使用户的会话延长此处设置的时间。 @@ -7965,7 +7965,7 @@ Bindings to groups/users are checked against the user of the event. 成功创建用户并添加到组 - This user will be added to the group "". + This user will be added to the group "". 此用户将会被添加到组 ""。 @@ -8203,7 +8203,13 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. 设置会话在被断开连接并需要重新授权之前持续的时间。 + + + Provider require enterprise. + + + Learn more - \ No newline at end of file + diff --git a/web/xliff/zh-Hant.xlf b/web/xliff/zh-Hant.xlf index 65794b706..35b356efa 100644 --- a/web/xliff/zh-Hant.xlf +++ b/web/xliff/zh-Hant.xlf @@ -6194,6 +6194,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more diff --git a/web/xliff/zh_TW.xlf b/web/xliff/zh_TW.xlf index 9a9b690bd..8ec2bf521 100644 --- a/web/xliff/zh_TW.xlf +++ b/web/xliff/zh_TW.xlf @@ -8083,6 +8083,12 @@ Bindings to groups/users are checked against the user of the event. Determines how long a session lasts before being disconnected and requiring re-authorization. + + + Provider require enterprise. + + + Learn more