Compare commits
73 Commits
beta-upgra
...
version/20
Author | SHA1 | Date | |
---|---|---|---|
be85eecac5 | |||
24385c9c68 | |||
e141a11475 | |||
b055adec2a | |||
772acb10d6 | |||
a7bf963409 | |||
317afc932a | |||
5e5a74eebf | |||
fa87519536 | |||
0deaf25b1f | |||
47d5fc26cc | |||
9a996e7176 | |||
554a26442d | |||
573517bf0a | |||
2cd68dfa87 | |||
8029a13be1 | |||
6900ffffd8 | |||
873aaf85f9 | |||
9c69f67778 | |||
6cf7a72831 | |||
7e3b325929 | |||
b916b612c7 | |||
b7c5fc3f1e | |||
a3ac5ec183 | |||
d30379ba93 | |||
12815526c1 | |||
ed2f0a2d5e | |||
536d776d02 | |||
f70d6432e7 | |||
cc08bfb18b | |||
79dcc30778 | |||
68a1bcf233 | |||
cd7de4c0b9 | |||
3195a75b9a | |||
886d7832df | |||
a3595a36d2 | |||
28ac00798c | |||
f4b0d6e85c | |||
daa3c91afc | |||
5eba598584 | |||
a6b16ecc68 | |||
a41924939b | |||
0afd3b121e | |||
a58374f065 | |||
8faec99bd6 | |||
6c27a2f783 | |||
78e4c313b5 | |||
f8140e1543 | |||
4405a04b0b | |||
7eb5fa6a24 | |||
216e8aff64 | |||
c91bbecb7b | |||
084b3eb039 | |||
557aadecc0 | |||
33b8c45f5c | |||
52132112f6 | |||
ff1510dedc | |||
c3398004ff | |||
47f09ac285 | |||
259c87fa37 | |||
80bb6c6274 | |||
f8c2fc2ead | |||
ea84ee0222 | |||
a695ffc224 | |||
9e22f007a8 | |||
6299fc7f81 | |||
a032fd529b | |||
ec78e56fbd | |||
ad7dedb61f | |||
8356ceaead | |||
228197ea5e | |||
27d3d4a534 | |||
f2dcbf9b1d |
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 2023.4.1
|
||||
current_version = 2023.5.3
|
||||
tag = True
|
||||
commit = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
||||
|
2
.github/workflows/ci-main.yml
vendored
2
.github/workflows/ci-main.yml
vendored
@ -112,7 +112,7 @@ jobs:
|
||||
- name: Setup authentik env
|
||||
uses: ./.github/actions/setup
|
||||
- name: Create k8s Kind Cluster
|
||||
uses: helm/kind-action@v1.5.0
|
||||
uses: helm/kind-action@v1.7.0
|
||||
- name: run integration
|
||||
run: |
|
||||
poetry run coverage run manage.py test tests/integration
|
||||
|
1
.github/workflows/ci-outpost.yml
vendored
1
.github/workflows/ci-outpost.yml
vendored
@ -135,4 +135,5 @@ jobs:
|
||||
set -x
|
||||
export GOOS=${{ matrix.goos }}
|
||||
export GOARCH=${{ matrix.goarch }}
|
||||
export CGO_ENABLED=0
|
||||
go build -tags=outpost_static_embed -v -o ./authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/${{ matrix.type }}
|
||||
|
7
.github/workflows/ghcr-retention.yml
vendored
7
.github/workflows/ghcr-retention.yml
vendored
@ -10,6 +10,11 @@ jobs:
|
||||
name: Delete old unused container images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- name: Delete 'dev' containers older than a week
|
||||
uses: snok/container-retention-policy@v2
|
||||
with:
|
||||
@ -18,5 +23,5 @@ jobs:
|
||||
account-type: org
|
||||
org-name: goauthentik
|
||||
untagged-only: false
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
skip-tags: gh-next,gh-main
|
||||
|
1
.github/workflows/release-publish.yml
vendored
1
.github/workflows/release-publish.yml
vendored
@ -123,6 +123,7 @@ jobs:
|
||||
set -x
|
||||
export GOOS=${{ matrix.goos }}
|
||||
export GOARCH=${{ matrix.goarch }}
|
||||
export CGO_ENABLED=0
|
||||
go build -tags=outpost_static_embed -v -o ./authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/${{ matrix.type }}
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
|
9
.github/workflows/release-tag.yml
vendored
9
.github/workflows/release-tag.yml
vendored
@ -22,18 +22,23 @@ jobs:
|
||||
docker-compose up --no-start
|
||||
docker-compose start postgresql redis
|
||||
docker-compose run -u root server test-all
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- name: Extract version number
|
||||
id: get_version
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
script: |
|
||||
return context.payload.ref.replace(/\/refs\/tags\/version\//, '');
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1.1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ steps.get_version.outputs.result }}
|
||||
|
9
.github/workflows/translation-compile.yml
vendored
9
.github/workflows/translation-compile.yml
vendored
@ -15,9 +15,14 @@ jobs:
|
||||
compile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
- name: Setup authentik env
|
||||
uses: ./.github/actions/setup
|
||||
- name: run compile
|
||||
@ -26,7 +31,7 @@ jobs:
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
id: cpr
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
branch: compile-backend-translation
|
||||
commit-message: "core: compile backend translations"
|
||||
title: "core: compile backend translations"
|
||||
|
11
.github/workflows/web-api-publish.yml
vendored
11
.github/workflows/web-api-publish.yml
vendored
@ -9,9 +9,14 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
- uses: actions/setup-node@v3.6.0
|
||||
with:
|
||||
node-version: "20"
|
||||
@ -33,7 +38,7 @@ jobs:
|
||||
- uses: peter-evans/create-pull-request@v5
|
||||
id: cpr
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
branch: update-web-api-client
|
||||
commit-message: "web: bump API Client version"
|
||||
title: "web: bump API Client version"
|
||||
@ -44,6 +49,6 @@ jobs:
|
||||
author: authentik bot <github-bot@goauthentik.io>
|
||||
- uses: peter-evans/enable-pull-request-automerge@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
merge-method: squash
|
||||
|
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
@ -1,10 +1,11 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"EditorConfig.EditorConfig",
|
||||
"bashmish.es6-string-css",
|
||||
"bpruitt-goddard.mermaid-markdown-syntax-highlighting",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"EditorConfig.EditorConfig",
|
||||
"esbenp.prettier-vscode",
|
||||
"github.vscode-github-actions",
|
||||
"golang.go",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"mechatroner.rainbow-csv",
|
||||
@ -15,6 +16,6 @@
|
||||
"ms-python.vscode-pylance",
|
||||
"redhat.vscode-yaml",
|
||||
"Tobermory.es6-string-html",
|
||||
"unifiedjs.vscode-mdx"
|
||||
"unifiedjs.vscode-mdx",
|
||||
]
|
||||
}
|
||||
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -48,5 +48,10 @@
|
||||
"ignoreCase": false
|
||||
}
|
||||
],
|
||||
"go.testFlags": ["-count=1"]
|
||||
"go.testFlags": [
|
||||
"-count=1"
|
||||
],
|
||||
"github-actions.workflows.pinned.workflows": [
|
||||
".github/workflows/ci-main.yml"
|
||||
]
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ COPY ./SECURITY.md /work/
|
||||
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /work/website
|
||||
RUN npm ci && npm run build-docs-only
|
||||
RUN npm ci --include=dev && npm run build-docs-only
|
||||
|
||||
# Stage 2: Build webui
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
|
||||
@ -17,7 +17,7 @@ COPY ./website /work/website/
|
||||
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /work/web
|
||||
RUN npm ci && npm run build
|
||||
RUN npm ci --include=dev && npm run build
|
||||
|
||||
# Stage 3: Poetry to requirements.txt export
|
||||
FROM docker.io/python:3.11.3-slim-bullseye AS poetry-locker
|
||||
|
@ -6,8 +6,8 @@ Authentik takes security very seriously. We follow the rules of [responsible dis
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| 2023.2.x | :white_check_mark: |
|
||||
| 2023.3.x | :white_check_mark: |
|
||||
| 2023.4.x | :white_check_mark: |
|
||||
| 2023.5.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
from os import environ
|
||||
from typing import Optional
|
||||
|
||||
__version__ = "2023.4.1"
|
||||
__version__ = "2023.5.3"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""core Configs API"""
|
||||
from os import path
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
@ -63,7 +63,7 @@ class ConfigView(APIView):
|
||||
"""Get all capabilities this server instance supports"""
|
||||
caps = []
|
||||
deb_test = settings.DEBUG or settings.TEST
|
||||
if path.ismount(settings.MEDIA_ROOT) or deb_test:
|
||||
if Path(settings.MEDIA_ROOT).is_mount() or deb_test:
|
||||
caps.append(Capabilities.CAN_SAVE_MEDIA)
|
||||
if GEOIP_READER.enabled:
|
||||
caps.append(Capabilities.CAN_GEO_IP)
|
||||
|
@ -11,8 +11,9 @@ from rest_framework.serializers import ListSerializer, ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.api.decorators import permission_required
|
||||
from authentik.blueprints.models import BlueprintInstance, BlueprintRetrievalFailed
|
||||
from authentik.blueprints.models import BlueprintInstance
|
||||
from authentik.blueprints.v1.importer import Importer
|
||||
from authentik.blueprints.v1.oci import OCI_PREFIX
|
||||
from authentik.blueprints.v1.tasks import apply_blueprint, blueprints_find_dict
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
@ -35,11 +36,12 @@ class BlueprintInstanceSerializer(ModelSerializer):
|
||||
"""Info about a single blueprint instance file"""
|
||||
|
||||
def validate_path(self, path: str) -> str:
|
||||
"""Ensure the path specified is retrievable"""
|
||||
try:
|
||||
BlueprintInstance(path=path).retrieve()
|
||||
except BlueprintRetrievalFailed as exc:
|
||||
raise ValidationError(exc) from exc
|
||||
"""Ensure the path (if set) specified is retrievable"""
|
||||
if path == "" or path.startswith(OCI_PREFIX):
|
||||
return path
|
||||
files: list[dict] = blueprints_find_dict.delay().get()
|
||||
if path not in [file["path"] for file in files]:
|
||||
raise ValidationError(_("Blueprint file does not exist"))
|
||||
return path
|
||||
|
||||
def validate_content(self, content: str) -> str:
|
||||
|
@ -10,7 +10,7 @@ from rest_framework.serializers import Serializer
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT, is_model_allowed
|
||||
from authentik.blueprints.v1.meta.registry import registry
|
||||
from authentik.blueprints.v1.meta.registry import BaseMetaModel, registry
|
||||
from authentik.lib.models import SerializerModel
|
||||
|
||||
LOGGER = get_logger()
|
||||
@ -74,14 +74,18 @@ class Command(BaseCommand):
|
||||
def build(self):
|
||||
"""Build all models into the schema"""
|
||||
for model in registry.get_models():
|
||||
if model._meta.abstract:
|
||||
continue
|
||||
if not is_model_allowed(model):
|
||||
continue
|
||||
model_instance: Model = model()
|
||||
if not isinstance(model_instance, SerializerModel):
|
||||
continue
|
||||
serializer = model_instance.serializer(
|
||||
if issubclass(model, BaseMetaModel):
|
||||
serializer_class = model.serializer()
|
||||
else:
|
||||
if model._meta.abstract:
|
||||
continue
|
||||
if not is_model_allowed(model):
|
||||
continue
|
||||
model_instance: Model = model()
|
||||
if not isinstance(model_instance, SerializerModel):
|
||||
continue
|
||||
serializer_class = model_instance.serializer
|
||||
serializer = serializer_class(
|
||||
context={
|
||||
SERIALIZER_CONTEXT_BLUEPRINT: False,
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ def check_blueprint_v1_file(BlueprintInstance: type, path: Path):
|
||||
enabled=True,
|
||||
managed_models=[],
|
||||
last_applied_hash="",
|
||||
metadata=metadata,
|
||||
metadata=metadata or {},
|
||||
)
|
||||
instance.save()
|
||||
|
||||
|
@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.serializers import Serializer
|
||||
from structlog import get_logger
|
||||
|
||||
from authentik.blueprints.v1.oci import BlueprintOCIClient, OCIException
|
||||
from authentik.blueprints.v1.oci import OCI_PREFIX, BlueprintOCIClient, OCIException
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.models import CreatedUpdatedModel, SerializerModel
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
@ -72,7 +72,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
|
||||
def retrieve_oci(self) -> str:
|
||||
"""Get blueprint from an OCI registry"""
|
||||
client = BlueprintOCIClient(self.path.replace("oci://", "https://"))
|
||||
client = BlueprintOCIClient(self.path.replace(OCI_PREFIX, "https://"))
|
||||
try:
|
||||
manifests = client.fetch_manifests()
|
||||
return client.fetch_blobs(manifests)
|
||||
@ -90,7 +90,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
|
||||
def retrieve(self) -> str:
|
||||
"""Retrieve blueprint contents"""
|
||||
if self.path.startswith("oci://"):
|
||||
if self.path.startswith(OCI_PREFIX):
|
||||
return self.retrieve_oci()
|
||||
if self.path != "":
|
||||
return self.retrieve_file()
|
||||
|
@ -32,6 +32,29 @@ class TestBlueprintOCI(TransactionTestCase):
|
||||
"foo",
|
||||
)
|
||||
|
||||
def test_successful_port(self):
|
||||
"""Successful retrieval with custom port"""
|
||||
with Mocker() as mocker:
|
||||
mocker.get(
|
||||
"https://ghcr.io:1234/v2/goauthentik/blueprints/test/manifests/latest",
|
||||
json={
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": OCI_MEDIA_TYPE,
|
||||
"digest": "foo",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
mocker.get("https://ghcr.io:1234/v2/goauthentik/blueprints/test/blobs/foo", text="foo")
|
||||
|
||||
self.assertEqual(
|
||||
BlueprintInstance(
|
||||
path="oci://ghcr.io:1234/goauthentik/blueprints/test:latest"
|
||||
).retrieve(),
|
||||
"foo",
|
||||
)
|
||||
|
||||
def test_manifests_error(self):
|
||||
"""Test manifests request erroring"""
|
||||
with Mocker() as mocker:
|
||||
|
@ -44,6 +44,14 @@ class TestBlueprintsV1API(APITestCase):
|
||||
),
|
||||
)
|
||||
|
||||
def test_api_oci(self):
|
||||
"""Test validation with OCI path"""
|
||||
res = self.client.post(
|
||||
reverse("authentik_api:blueprintinstance-list"),
|
||||
data={"name": "foo", "path": "oci://foo/bar"},
|
||||
)
|
||||
self.assertEqual(res.status_code, 201)
|
||||
|
||||
def test_api_blank(self):
|
||||
"""Test blank"""
|
||||
res = self.client.post(
|
||||
|
@ -19,6 +19,7 @@ from authentik.lib.sentry import SentryIgnoredException
|
||||
from authentik.lib.utils.http import authentik_user_agent
|
||||
|
||||
OCI_MEDIA_TYPE = "application/vnd.goauthentik.blueprint.v1+yaml"
|
||||
OCI_PREFIX = "oci://"
|
||||
|
||||
|
||||
class OCIException(SentryIgnoredException):
|
||||
@ -39,11 +40,16 @@ class BlueprintOCIClient:
|
||||
self.logger = get_logger().bind(url=self.sanitized_url)
|
||||
|
||||
self.ref = "latest"
|
||||
# Remove the leading slash of the path to convert it to an image name
|
||||
path = self.url.path[1:]
|
||||
if ":" in self.url.path:
|
||||
if ":" in path:
|
||||
# if there's a colon in the path, use everything after it as a ref
|
||||
path, _, self.ref = path.partition(":")
|
||||
base_url = f"https://{self.url.hostname}"
|
||||
if self.url.port:
|
||||
base_url += f":{self.url.port}"
|
||||
self.client = NewClient(
|
||||
f"https://{self.url.hostname}",
|
||||
base_url,
|
||||
WithUserAgent(authentik_user_agent()),
|
||||
WithUsernamePassword(self.url.username, self.url.password),
|
||||
WithDefaultName(path),
|
||||
|
@ -28,6 +28,7 @@ from authentik.blueprints.models import (
|
||||
from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata, EntryInvalidError
|
||||
from authentik.blueprints.v1.importer import Importer
|
||||
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
|
||||
from authentik.blueprints.v1.oci import OCI_PREFIX
|
||||
from authentik.events.monitored_tasks import (
|
||||
MonitoredTask,
|
||||
TaskResult,
|
||||
@ -228,7 +229,7 @@ def apply_blueprint(self: MonitoredTask, instance_pk: str):
|
||||
def clear_failed_blueprints():
|
||||
"""Remove blueprints which couldn't be fetched"""
|
||||
# Exclude OCI blueprints as those might be temporarily unavailable
|
||||
for blueprint in BlueprintInstance.objects.exclude(path__startswith="oci://"):
|
||||
for blueprint in BlueprintInstance.objects.exclude(path__startswith=OCI_PREFIX):
|
||||
try:
|
||||
blueprint.retrieve()
|
||||
except BlueprintRetrievalFailed:
|
||||
|
@ -1,4 +1,6 @@
|
||||
"""Provider API Views"""
|
||||
from django.db.models import QuerySet
|
||||
from django.db.models.query import Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_filters.filters import BooleanFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
@ -56,17 +58,22 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer):
|
||||
|
||||
|
||||
class ProviderFilter(FilterSet):
|
||||
"""Filter for groups"""
|
||||
"""Filter for providers"""
|
||||
|
||||
application__isnull = BooleanFilter(
|
||||
field_name="application",
|
||||
lookup_expr="isnull",
|
||||
)
|
||||
application__isnull = BooleanFilter(method="filter_application__isnull")
|
||||
backchannel_only = BooleanFilter(
|
||||
method="filter_backchannel_only",
|
||||
)
|
||||
|
||||
def filter_backchannel_only(self, queryset, name, value):
|
||||
def filter_application__isnull(self, queryset: QuerySet, name, value):
|
||||
"""Only return providers that are neither assigned to application,
|
||||
both as provider or application provider"""
|
||||
return queryset.filter(
|
||||
Q(backchannel_application__isnull=value, is_backchannel=True)
|
||||
| Q(application__isnull=value)
|
||||
)
|
||||
|
||||
def filter_backchannel_only(self, queryset: QuerySet, name, value):
|
||||
"""Only return backchannel providers"""
|
||||
return queryset.filter(is_backchannel=value)
|
||||
|
||||
|
@ -106,7 +106,7 @@ class UserSerializer(ModelSerializer):
|
||||
avatar = CharField(read_only=True)
|
||||
attributes = JSONField(validators=[is_dict], required=False)
|
||||
groups = PrimaryKeyRelatedField(
|
||||
allow_empty=True, many=True, source="ak_groups", queryset=Group.objects.all()
|
||||
allow_empty=True, many=True, source="ak_groups", queryset=Group.objects.all(), default=list
|
||||
)
|
||||
groups_obj = ListSerializer(child=UserGroupSerializer(), read_only=True, source="ak_groups")
|
||||
uid = CharField(read_only=True)
|
||||
|
@ -28,7 +28,7 @@ from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSI
|
||||
from authentik.lib.utils.urls import redirect_with_qs
|
||||
from authentik.lib.views import bad_request_message
|
||||
from authentik.policies.denied import AccessDeniedResponse
|
||||
from authentik.policies.utils import delete_none_keys
|
||||
from authentik.policies.utils import delete_none_values
|
||||
from authentik.stages.password import BACKEND_INBUILT
|
||||
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||
@ -329,7 +329,7 @@ class SourceFlowManager:
|
||||
)
|
||||
],
|
||||
**{
|
||||
PLAN_CONTEXT_PROMPT: delete_none_keys(self.enroll_info),
|
||||
PLAN_CONTEXT_PROMPT: delete_none_values(self.enroll_info),
|
||||
PLAN_CONTEXT_USER_PATH: self.source.get_user_path(),
|
||||
},
|
||||
)
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
{% block head %}
|
||||
<script src="{% static 'dist/user/UserInterface.js' %}?version={{ version }}" type="module"></script>
|
||||
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)">
|
||||
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
|
||||
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)">
|
||||
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)">
|
||||
<link rel="icon" href="{{ tenant.branding_favicon }}">
|
||||
<link rel="shortcut icon" href="{{ tenant.branding_favicon }}">
|
||||
{% include "base/header_js.html" %}
|
||||
|
@ -7,7 +7,6 @@ from smtplib import SMTPException
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models import Count, ExpressionWrapper, F
|
||||
from django.db.models.fields import DurationField
|
||||
@ -207,9 +206,7 @@ class Event(SerializerModel, ExpiringModel):
|
||||
self.user = get_user(user)
|
||||
return self
|
||||
|
||||
def from_http(
|
||||
self, request: HttpRequest, user: Optional[settings.AUTH_USER_MODEL] = None
|
||||
) -> "Event":
|
||||
def from_http(self, request: HttpRequest, user: Optional[User] = None) -> "Event":
|
||||
"""Add data from a Django-HttpRequest, allowing the creation of
|
||||
Events independently from requests.
|
||||
`user` arguments optionally overrides user from requests."""
|
||||
|
@ -87,9 +87,9 @@ class TaskInfo:
|
||||
except TypeError:
|
||||
duration = 0
|
||||
GAUGE_TASKS.labels(
|
||||
task_name=self.task_name,
|
||||
task_name=self.task_name.split(":")[0],
|
||||
task_uid=self.result.uid or "",
|
||||
status=self.result.status,
|
||||
status=self.result.status.value,
|
||||
).set(duration)
|
||||
|
||||
def save(self, timeout_hours=6):
|
||||
|
@ -2,6 +2,7 @@
|
||||
import re
|
||||
from copy import copy
|
||||
from dataclasses import asdict, is_dataclass
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from types import GeneratorType
|
||||
from typing import Any, Optional
|
||||
@ -126,6 +127,8 @@ def sanitize_item(value: Any) -> Any:
|
||||
return str(value)
|
||||
if isinstance(value, YAMLTag):
|
||||
return str(value)
|
||||
if isinstance(value, Enum):
|
||||
return value.value
|
||||
if isinstance(value, type):
|
||||
return {
|
||||
"type": value.__name__,
|
||||
|
@ -5,6 +5,7 @@ from contextlib import contextmanager
|
||||
from glob import glob
|
||||
from json import dumps, loads
|
||||
from json.decoder import JSONDecodeError
|
||||
from pathlib import Path
|
||||
from sys import argv, stderr
|
||||
from time import time
|
||||
from typing import Any
|
||||
@ -42,22 +43,25 @@ class ConfigLoader:
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.__config = {}
|
||||
base_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../.."))
|
||||
for path in SEARCH_PATHS:
|
||||
base_dir = Path(__file__).parent.joinpath(Path("../..")).resolve()
|
||||
for _path in SEARCH_PATHS:
|
||||
path = Path(_path)
|
||||
# Check if path is relative, and if so join with base_dir
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(base_dir, path)
|
||||
if os.path.isfile(path) and os.path.exists(path):
|
||||
if not path.is_absolute():
|
||||
path = base_dir / path
|
||||
if path.is_file() and path.exists():
|
||||
# Path is an existing file, so we just read it and update our config with it
|
||||
self.update_from_file(path)
|
||||
elif os.path.isdir(path) and os.path.exists(path):
|
||||
elif path.is_dir() and path.exists():
|
||||
# Path is an existing dir, so we try to read the env config from it
|
||||
env_paths = [
|
||||
os.path.join(path, ENVIRONMENT + ".yml"),
|
||||
os.path.join(path, ENVIRONMENT + ".env.yml"),
|
||||
path / Path(ENVIRONMENT + ".yml"),
|
||||
path / Path(ENVIRONMENT + ".env.yml"),
|
||||
path / Path(ENVIRONMENT + ".yaml"),
|
||||
path / Path(ENVIRONMENT + ".env.yaml"),
|
||||
]
|
||||
for env_file in env_paths:
|
||||
if os.path.isfile(env_file) and os.path.exists(env_file):
|
||||
if env_file.is_file() and env_file.exists():
|
||||
# Update config with env file
|
||||
self.update_from_file(env_file)
|
||||
self.update_from_env()
|
||||
@ -99,13 +103,13 @@ class ConfigLoader:
|
||||
value = url.query
|
||||
return value
|
||||
|
||||
def update_from_file(self, path: str):
|
||||
def update_from_file(self, path: Path):
|
||||
"""Update config from file contents"""
|
||||
try:
|
||||
with open(path, encoding="utf8") as file:
|
||||
try:
|
||||
self.update(self.__config, yaml.safe_load(file))
|
||||
self.log("debug", "Loaded config", file=path)
|
||||
self.log("debug", "Loaded config", file=str(path))
|
||||
self.loaded_file.append(path)
|
||||
except yaml.YAMLError as exc:
|
||||
raise ImproperlyConfigured from exc
|
||||
|
@ -140,19 +140,21 @@ class BaseEvaluator:
|
||||
def expr_event_create(self, action: str, **kwargs):
|
||||
"""Create event with supplied data and try to extract as much relevant data
|
||||
from the context"""
|
||||
context = self._context.copy()
|
||||
# If the result was a complex variable, we don't want to re-use it
|
||||
self._context.pop("result", None)
|
||||
self._context.pop("handler", None)
|
||||
kwargs["context"] = self._context
|
||||
context.pop("result", None)
|
||||
context.pop("handler", None)
|
||||
event_kwargs = context
|
||||
event_kwargs.update(kwargs)
|
||||
event = Event.new(
|
||||
action,
|
||||
app=self._filename,
|
||||
**kwargs,
|
||||
**event_kwargs,
|
||||
)
|
||||
if "request" in self._context and isinstance(self._context["request"], PolicyRequest):
|
||||
policy_request: PolicyRequest = self._context["request"]
|
||||
if "request" in context and isinstance(context["request"], PolicyRequest):
|
||||
policy_request: PolicyRequest = context["request"]
|
||||
if policy_request.http_request:
|
||||
event.from_http(policy_request)
|
||||
event.from_http(policy_request.http_request)
|
||||
return
|
||||
event.save()
|
||||
|
||||
|
@ -19,7 +19,15 @@ def fallback_names(app: str, model: str, field: str):
|
||||
if value not in seen_names:
|
||||
seen_names.append(value)
|
||||
continue
|
||||
new_value = value + "_2"
|
||||
separator = "_"
|
||||
suffix_index = 2
|
||||
while (
|
||||
klass.objects.using(db_alias)
|
||||
.filter(**{field: f"{value}{separator}{suffix_index}"})
|
||||
.exists()
|
||||
):
|
||||
suffix_index += 1
|
||||
new_value = f"{value}{separator}{suffix_index}"
|
||||
setattr(obj, field, new_value)
|
||||
obj.save()
|
||||
|
||||
|
@ -2,28 +2,41 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user
|
||||
from authentik.events.models import Event
|
||||
from authentik.lib.expression.evaluator import BaseEvaluator
|
||||
from authentik.lib.generators import generate_id
|
||||
|
||||
|
||||
class TestEvaluator(TestCase):
|
||||
"""Test Evaluator base functions"""
|
||||
|
||||
def test_regex_match(self):
|
||||
def test_expr_regex_match(self):
|
||||
"""Test expr_regex_match"""
|
||||
self.assertFalse(BaseEvaluator.expr_regex_match("foo", "bar"))
|
||||
self.assertTrue(BaseEvaluator.expr_regex_match("foo", "foo"))
|
||||
|
||||
def test_regex_replace(self):
|
||||
def test_expr_regex_replace(self):
|
||||
"""Test expr_regex_replace"""
|
||||
self.assertEqual(BaseEvaluator.expr_regex_replace("foo", "o", "a"), "faa")
|
||||
|
||||
def test_user_by(self):
|
||||
def test_expr_user_by(self):
|
||||
"""Test expr_user_by"""
|
||||
user = create_test_admin_user()
|
||||
self.assertIsNotNone(BaseEvaluator.expr_user_by(username=user.username))
|
||||
self.assertIsNone(BaseEvaluator.expr_user_by(username="bar"))
|
||||
self.assertIsNone(BaseEvaluator.expr_user_by(foo="bar"))
|
||||
|
||||
def test_is_group_member(self):
|
||||
def test_expr_is_group_member(self):
|
||||
"""Test expr_is_group_member"""
|
||||
self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test"))
|
||||
|
||||
def test_expr_event_create(self):
|
||||
"""Test expr_event_create"""
|
||||
evaluator = BaseEvaluator(generate_id())
|
||||
evaluator._context = {
|
||||
"foo": "bar",
|
||||
}
|
||||
evaluator.evaluate("ak_create_event('foo', bar='baz')")
|
||||
event = Event.objects.filter(action="custom_foo").first()
|
||||
self.assertIsNotNone(event)
|
||||
self.assertEqual(event.context, {"bar": "baz", "foo": "bar"})
|
||||
|
@ -42,12 +42,15 @@ from authentik.providers.ldap.controllers.docker import LDAPDockerController
|
||||
from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
|
||||
from authentik.providers.proxy.controllers.docker import ProxyDockerController
|
||||
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
|
||||
from authentik.providers.radius.controllers.docker import RadiusDockerController
|
||||
from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
|
||||
from authentik.root.celery import CELERY_APP
|
||||
|
||||
LOGGER = get_logger()
|
||||
CACHE_KEY_OUTPOST_DOWN = "goauthentik.io/outposts/teardown/%s"
|
||||
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def controller_for_outpost(outpost: Outpost) -> Optional[type[BaseController]]:
|
||||
"""Get a controller for the outpost, when a service connection is defined"""
|
||||
if not outpost.service_connection:
|
||||
@ -63,6 +66,11 @@ def controller_for_outpost(outpost: Outpost) -> Optional[type[BaseController]]:
|
||||
return LDAPDockerController
|
||||
if isinstance(service_connection, KubernetesServiceConnection):
|
||||
return LDAPKubernetesController
|
||||
if outpost.type == OutpostType.RADIUS:
|
||||
if isinstance(service_connection, DockerServiceConnection):
|
||||
return RadiusDockerController
|
||||
if isinstance(service_connection, KubernetesServiceConnection):
|
||||
return RadiusKubernetesController
|
||||
return None
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
from typing import Any
|
||||
|
||||
|
||||
def delete_none_keys(dict_: dict[Any, Any]) -> dict[Any, Any]:
|
||||
def delete_none_values(dict_: dict[Any, Any]) -> dict[Any, Any]:
|
||||
"""Remove any keys from `dict_` that are None."""
|
||||
new_dict = {}
|
||||
for key, value in dict_.items():
|
||||
|
@ -1,4 +1,8 @@
|
||||
"""LDAPProvider API Views"""
|
||||
from django.db.models import QuerySet
|
||||
from django.db.models.query import Q
|
||||
from django_filters.filters import BooleanFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from rest_framework.fields import CharField, ListField, SerializerMethodField
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
@ -29,24 +33,41 @@ class LDAPProviderSerializer(ProviderSerializer):
|
||||
extra_kwargs = ProviderSerializer.Meta.extra_kwargs
|
||||
|
||||
|
||||
class LDAPProviderFilter(FilterSet):
|
||||
"""LDAP Provider filters"""
|
||||
|
||||
application__isnull = BooleanFilter(method="filter_application__isnull")
|
||||
|
||||
def filter_application__isnull(self, queryset: QuerySet, name, value):
|
||||
"""Only return providers that are neither assigned to application,
|
||||
both as provider or application provider"""
|
||||
return queryset.filter(
|
||||
Q(backchannel_application__isnull=value) | Q(application__isnull=value)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = LDAPProvider
|
||||
fields = {
|
||||
"application": ["isnull"],
|
||||
"name": ["iexact"],
|
||||
"authorization_flow__slug": ["iexact"],
|
||||
"base_dn": ["iexact"],
|
||||
"search_group__group_uuid": ["iexact"],
|
||||
"search_group__name": ["iexact"],
|
||||
"certificate__kp_uuid": ["iexact"],
|
||||
"certificate__name": ["iexact"],
|
||||
"tls_server_name": ["iexact"],
|
||||
"uid_start_number": ["iexact"],
|
||||
"gid_start_number": ["iexact"],
|
||||
}
|
||||
|
||||
|
||||
class LDAPProviderViewSet(UsedByMixin, ModelViewSet):
|
||||
"""LDAPProvider Viewset"""
|
||||
|
||||
queryset = LDAPProvider.objects.all()
|
||||
serializer_class = LDAPProviderSerializer
|
||||
filterset_fields = {
|
||||
"application": ["isnull"],
|
||||
"name": ["iexact"],
|
||||
"authorization_flow__slug": ["iexact"],
|
||||
"base_dn": ["iexact"],
|
||||
"search_group__group_uuid": ["iexact"],
|
||||
"search_group__name": ["iexact"],
|
||||
"certificate__kp_uuid": ["iexact"],
|
||||
"certificate__name": ["iexact"],
|
||||
"tls_server_name": ["iexact"],
|
||||
"uid_start_number": ["iexact"],
|
||||
"gid_start_number": ["iexact"],
|
||||
}
|
||||
filterset_class = LDAPProviderFilter
|
||||
search_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""RadiusProvider API Views"""
|
||||
from rest_framework.fields import CharField
|
||||
from rest_framework.fields import CharField, ListField
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
|
||||
@ -11,6 +11,8 @@ from authentik.providers.radius.models import RadiusProvider
|
||||
class RadiusProviderSerializer(ProviderSerializer):
|
||||
"""RadiusProvider Serializer"""
|
||||
|
||||
outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
|
||||
|
||||
class Meta:
|
||||
model = RadiusProvider
|
||||
fields = ProviderSerializer.Meta.fields + [
|
||||
@ -18,6 +20,7 @@ class RadiusProviderSerializer(ProviderSerializer):
|
||||
# Shared secret is not a write-only field, as
|
||||
# an admin might have to view it
|
||||
"shared_secret",
|
||||
"outpost_set",
|
||||
]
|
||||
extra_kwargs = ProviderSerializer.Meta.extra_kwargs
|
||||
|
||||
|
@ -24,8 +24,8 @@ class SCIMProviderSerializer(ProviderSerializer):
|
||||
"property_mappings",
|
||||
"property_mappings_group",
|
||||
"component",
|
||||
"assigned_application_slug",
|
||||
"assigned_application_name",
|
||||
"assigned_backchannel_application_slug",
|
||||
"assigned_backchannel_application_name",
|
||||
"verbose_name",
|
||||
"verbose_name_plural",
|
||||
"meta_model_name",
|
||||
|
@ -51,7 +51,7 @@ class SCIMClient(Generic[T, SchemaType]):
|
||||
},
|
||||
)
|
||||
except RequestException as exc:
|
||||
raise SCIMRequestException(None) from exc
|
||||
raise SCIMRequestException(message="Failed to send request") from exc
|
||||
self.logger.debug("scim request", path=path, method=method, **kwargs)
|
||||
if response.status_code >= 400:
|
||||
if response.status_code == 404:
|
||||
|
@ -2,10 +2,10 @@
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import ValidationError
|
||||
from pydanticscim.responses import SCIMError
|
||||
from requests import Response
|
||||
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
from authentik.providers.scim.clients.schema import SCIMError
|
||||
|
||||
|
||||
class StopSync(SentryIgnoredException):
|
||||
@ -16,7 +16,8 @@ class StopSync(SentryIgnoredException):
|
||||
self.obj = obj
|
||||
self.mapping = mapping
|
||||
|
||||
def __str__(self) -> str:
|
||||
def detail(self) -> str:
|
||||
"""Get human readable details of this error"""
|
||||
msg = f"Error {str(self.exc)}, caused by {self.obj}"
|
||||
|
||||
if self.mapping:
|
||||
@ -28,19 +29,22 @@ class SCIMRequestException(SentryIgnoredException):
|
||||
"""Exception raised when an SCIM request fails"""
|
||||
|
||||
_response: Optional[Response]
|
||||
_message: Optional[str]
|
||||
|
||||
def __init__(self, response: Optional[Response] = None) -> None:
|
||||
def __init__(self, response: Optional[Response] = None, message: Optional[str] = None) -> None:
|
||||
self._response = response
|
||||
self._message = message
|
||||
|
||||
def __str__(self) -> str:
|
||||
def detail(self) -> str:
|
||||
"""Get human readable details of this error"""
|
||||
if not self._response:
|
||||
return super().__str__()
|
||||
return self._message
|
||||
try:
|
||||
error = SCIMError.parse_raw(self._response.text)
|
||||
return error.detail
|
||||
except ValidationError:
|
||||
pass
|
||||
return super().__str__()
|
||||
return self._message
|
||||
|
||||
|
||||
class ResourceMissing(SCIMRequestException):
|
||||
|
@ -8,7 +8,7 @@ from authentik.core.exceptions import PropertyMappingExpressionException
|
||||
from authentik.core.models import Group
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.lib.utils.errors import exception_to_string
|
||||
from authentik.policies.utils import delete_none_keys
|
||||
from authentik.policies.utils import delete_none_values
|
||||
from authentik.providers.scim.clients.base import SCIMClient
|
||||
from authentik.providers.scim.clients.exceptions import (
|
||||
ResourceMissing,
|
||||
@ -74,7 +74,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroupSchema]):
|
||||
if not raw_scim_group:
|
||||
raise StopSync(ValueError("No group mappings configured"), obj)
|
||||
try:
|
||||
scim_group = SCIMGroupSchema.parse_obj(delete_none_keys(raw_scim_group))
|
||||
scim_group = SCIMGroupSchema.parse_obj(delete_none_values(raw_scim_group))
|
||||
except ValidationError as exc:
|
||||
raise StopSync(exc, obj) from exc
|
||||
if not scim_group.externalId:
|
||||
@ -130,10 +130,8 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroupSchema]):
|
||||
scim_group.id,
|
||||
PatchOperation(
|
||||
op=PatchOp.replace,
|
||||
value={
|
||||
"id": connection.id,
|
||||
"displayName": group.name,
|
||||
},
|
||||
path="displayName",
|
||||
value=scim_group.displayName,
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -3,6 +3,7 @@ from typing import Optional
|
||||
|
||||
from pydanticscim.group import Group as BaseGroup
|
||||
from pydanticscim.responses import PatchRequest as BasePatchRequest
|
||||
from pydanticscim.responses import SCIMError as BaseSCIMError
|
||||
from pydanticscim.service_provider import Bulk, ChangePassword, Filter, Patch
|
||||
from pydanticscim.service_provider import (
|
||||
ServiceProviderConfiguration as BaseServiceProviderConfiguration,
|
||||
@ -52,3 +53,9 @@ class PatchRequest(BasePatchRequest):
|
||||
"""PatchRequest which correctly sets schemas"""
|
||||
|
||||
schemas: tuple[str] = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
|
||||
|
||||
|
||||
class SCIMError(BaseSCIMError):
|
||||
"""SCIM error with optional status code"""
|
||||
|
||||
status: Optional[int]
|
||||
|
@ -6,7 +6,7 @@ from authentik.core.exceptions import PropertyMappingExpressionException
|
||||
from authentik.core.models import User
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.lib.utils.errors import exception_to_string
|
||||
from authentik.policies.utils import delete_none_keys
|
||||
from authentik.policies.utils import delete_none_values
|
||||
from authentik.providers.scim.clients.base import SCIMClient
|
||||
from authentik.providers.scim.clients.exceptions import ResourceMissing, StopSync
|
||||
from authentik.providers.scim.clients.schema import User as SCIMUserSchema
|
||||
@ -64,7 +64,7 @@ class SCIMUserClient(SCIMClient[User, SCIMUserSchema]):
|
||||
if not raw_scim_user:
|
||||
raise StopSync(ValueError("No user mappings configured"), obj)
|
||||
try:
|
||||
scim_user = SCIMUserSchema.parse_obj(delete_none_keys(raw_scim_user))
|
||||
scim_user = SCIMUserSchema.parse_obj(delete_none_values(raw_scim_user))
|
||||
except ValidationError as exc:
|
||||
raise StopSync(exc, obj) from exc
|
||||
if not scim_user.externalId:
|
||||
|
@ -42,7 +42,9 @@ def scim_sync_all():
|
||||
@CELERY_APP.task(bind=True, base=MonitoredTask)
|
||||
def scim_sync(self: MonitoredTask, provider_pk: int) -> None:
|
||||
"""Run SCIM full sync for provider"""
|
||||
provider: SCIMProvider = SCIMProvider.objects.filter(pk=provider_pk).first()
|
||||
provider: SCIMProvider = SCIMProvider.objects.filter(
|
||||
pk=provider_pk, backchannel_application__isnull=False
|
||||
).first()
|
||||
if not provider:
|
||||
return
|
||||
self.set_uid(slugify(provider.name))
|
||||
@ -87,10 +89,10 @@ def scim_sync_users(page: int, provider_pk: int):
|
||||
LOGGER.warning("failed to sync user", exc=exc, user=user)
|
||||
messages.append(
|
||||
_(
|
||||
"Failed to sync user due to remote error %(name)s: %(error)s"
|
||||
"Failed to sync user %(user_name)s due to remote error: %(error)s"
|
||||
% {
|
||||
"name": user.username,
|
||||
"error": str(exc),
|
||||
"user_name": user.username,
|
||||
"error": exc.detail(),
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -100,7 +102,7 @@ def scim_sync_users(page: int, provider_pk: int):
|
||||
_(
|
||||
"Stopping sync due to error: %(error)s"
|
||||
% {
|
||||
"error": str(exc),
|
||||
"error": exc.detail(),
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -128,10 +130,10 @@ def scim_sync_group(page: int, provider_pk: int):
|
||||
LOGGER.warning("failed to sync group", exc=exc, group=group)
|
||||
messages.append(
|
||||
_(
|
||||
"Failed to sync group due to remote error %(name)s: %(error)s"
|
||||
"Failed to sync group %(group_name)s due to remote error: %(error)s"
|
||||
% {
|
||||
"name": group.name,
|
||||
"error": str(exc),
|
||||
"group_name": group.name,
|
||||
"error": exc.detail(),
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -141,7 +143,7 @@ def scim_sync_group(page: int, provider_pk: int):
|
||||
_(
|
||||
"Stopping sync due to error: %(error)s"
|
||||
% {
|
||||
"error": str(exc),
|
||||
"error": exc.detail(),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -36,6 +36,7 @@ class SCIMMembershipTests(TestCase):
|
||||
slug=generate_id(),
|
||||
)
|
||||
self.app.backchannel_providers.add(self.provider)
|
||||
self.provider.save()
|
||||
self.provider.property_mappings.set(
|
||||
[SCIMMapping.objects.get(managed="goauthentik.io/providers/scim/user")]
|
||||
)
|
||||
@ -91,7 +92,6 @@ class SCIMMembershipTests(TestCase):
|
||||
"active": True,
|
||||
"externalId": user.uid,
|
||||
"name": {"familyName": "", "formatted": "", "givenName": ""},
|
||||
"photos": [],
|
||||
"displayName": "",
|
||||
"userName": user.username,
|
||||
},
|
||||
@ -177,7 +177,6 @@ class SCIMMembershipTests(TestCase):
|
||||
"emails": [],
|
||||
"externalId": user.uid,
|
||||
"name": {"familyName": "", "formatted": "", "givenName": ""},
|
||||
"photos": [],
|
||||
"userName": user.username,
|
||||
},
|
||||
)
|
||||
|
@ -81,7 +81,6 @@ class SCIMUserTests(TestCase):
|
||||
"givenName": uid,
|
||||
},
|
||||
"displayName": uid,
|
||||
"photos": [],
|
||||
"userName": uid,
|
||||
},
|
||||
)
|
||||
@ -137,7 +136,6 @@ class SCIMUserTests(TestCase):
|
||||
"formatted": uid,
|
||||
"givenName": uid,
|
||||
},
|
||||
"photos": [],
|
||||
"userName": uid,
|
||||
},
|
||||
)
|
||||
@ -190,7 +188,6 @@ class SCIMUserTests(TestCase):
|
||||
"givenName": uid,
|
||||
},
|
||||
"displayName": uid,
|
||||
"photos": [],
|
||||
"userName": uid,
|
||||
},
|
||||
)
|
||||
@ -258,7 +255,6 @@ class SCIMUserTests(TestCase):
|
||||
"givenName": uid,
|
||||
},
|
||||
"displayName": uid,
|
||||
"photos": [],
|
||||
"userName": uid,
|
||||
},
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ import importlib
|
||||
import logging
|
||||
import os
|
||||
from hashlib import sha512
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import structlog
|
||||
@ -19,11 +20,9 @@ from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BAC
|
||||
|
||||
LOGGER = structlog.get_logger()
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
STATIC_ROOT = BASE_DIR + "/static"
|
||||
STATICFILES_DIRS = [BASE_DIR + "/web"]
|
||||
MEDIA_ROOT = BASE_DIR + "/media"
|
||||
BASE_DIR = Path(__file__).absolute().parent.parent.parent
|
||||
STATICFILES_DIRS = [BASE_DIR / Path("web")]
|
||||
MEDIA_ROOT = BASE_DIR / Path("media")
|
||||
|
||||
DEBUG = CONFIG.y_bool("debug")
|
||||
SECRET_KEY = CONFIG.y("secret_key")
|
||||
|
@ -55,7 +55,7 @@ class LDAPBackend(InbuiltBackend):
|
||||
"""Attempt authentication by binding to the LDAP server as `user`. This
|
||||
method should be avoided as its slow to do the bind."""
|
||||
# Try to bind as new user
|
||||
LOGGER.debug("Attempting Binding as user", user=user)
|
||||
LOGGER.debug("Attempting to bind as user", user=user)
|
||||
try:
|
||||
temp_connection = source.connection(
|
||||
connection_kwargs={
|
||||
@ -65,8 +65,8 @@ class LDAPBackend(InbuiltBackend):
|
||||
)
|
||||
temp_connection.bind()
|
||||
return user
|
||||
except LDAPInvalidCredentialsResult as exception:
|
||||
LOGGER.debug("LDAPInvalidCredentialsResult", user=user, error=exception)
|
||||
except LDAPException as exception:
|
||||
LOGGER.warning(exception)
|
||||
except LDAPInvalidCredentialsResult as exc:
|
||||
LOGGER.debug("invalid LDAP credentials", user=user, exc=exc)
|
||||
except LDAPException as exc:
|
||||
LOGGER.warning("failed to bind to LDAP", exc=exc)
|
||||
return None
|
||||
|
@ -6,6 +6,7 @@ from django.dispatch import receiver
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from ldap3.core.exceptions import LDAPOperationResult
|
||||
from rest_framework.serializers import ValidationError
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.core.signals import password_changed
|
||||
@ -20,6 +21,8 @@ from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
|
||||
from authentik.sources.ldap.tasks import ldap_sync
|
||||
from authentik.stages.prompt.signals import password_validate
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@receiver(post_save, sender=LDAPSource)
|
||||
def sync_ldap_source_on_save(sender, instance: LDAPSource, **_):
|
||||
@ -67,9 +70,13 @@ def ldap_sync_password(sender, user: User, password: str, **_):
|
||||
try:
|
||||
changer.change_password(user, password)
|
||||
except LDAPOperationResult as exc:
|
||||
LOGGER.warning("failed to set LDAP password", exc=exc)
|
||||
Event.new(
|
||||
EventAction.CONFIGURATION_ERROR,
|
||||
message=f"Result: {exc.result}, Description {exc.description}",
|
||||
message=(
|
||||
"Failed to change password in LDAP source due to remote error: "
|
||||
f"{exc.result}, {exc.message}, {exc.description}"
|
||||
),
|
||||
source=source,
|
||||
).set_user(user).save()
|
||||
raise ValidationError("Failed to set password") from exc
|
||||
|
@ -135,9 +135,9 @@ class BaseLDAPSynchronizer:
|
||||
if key == "attributes":
|
||||
continue
|
||||
setattr(instance, key, value)
|
||||
final_atttributes = {}
|
||||
MERGE_LIST_UNIQUE.merge(final_atttributes, instance.attributes)
|
||||
MERGE_LIST_UNIQUE.merge(final_atttributes, data.get("attributes", {}))
|
||||
instance.attributes = final_atttributes
|
||||
final_attributes = {}
|
||||
MERGE_LIST_UNIQUE.merge(final_attributes, instance.attributes)
|
||||
MERGE_LIST_UNIQUE.merge(final_attributes, data.get("attributes", {}))
|
||||
instance.attributes = final_attributes
|
||||
instance.save()
|
||||
return (instance, False)
|
||||
|
@ -21,7 +21,7 @@ from authentik.core.models import (
|
||||
from authentik.core.sources.flow_manager import SourceFlowManager
|
||||
from authentik.lib.expression.evaluator import BaseEvaluator
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.policies.utils import delete_none_keys
|
||||
from authentik.policies.utils import delete_none_values
|
||||
from authentik.sources.saml.exceptions import (
|
||||
InvalidSignature,
|
||||
MismatchedRequestID,
|
||||
@ -160,7 +160,7 @@ class ResponseProcessor:
|
||||
self._source,
|
||||
self._http_request,
|
||||
name_id,
|
||||
delete_none_keys(self.get_attributes()),
|
||||
delete_none_values(self.get_attributes()),
|
||||
)
|
||||
|
||||
def _get_name_id(self) -> "Element":
|
||||
@ -237,7 +237,7 @@ class ResponseProcessor:
|
||||
self._source,
|
||||
self._http_request,
|
||||
name_id.text,
|
||||
delete_none_keys(self.get_attributes()),
|
||||
delete_none_values(self.get_attributes()),
|
||||
)
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ class AuthenticatorSMSStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
||||
"From": self.from_number,
|
||||
"To": device.phone_number,
|
||||
"Body": token,
|
||||
"Message": self.get_message(token),
|
||||
"Message": str(self.get_message(token)),
|
||||
}
|
||||
|
||||
if self.mapping:
|
||||
|
@ -8,7 +8,7 @@ from authentik.flows.models import Stage
|
||||
|
||||
|
||||
class DenyStage(Stage):
|
||||
"""Cancells the current flow."""
|
||||
"""Cancels the current flow."""
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[BaseSerializer]:
|
||||
|
@ -5,10 +5,10 @@ from authentik.flows.stage import StageView
|
||||
|
||||
|
||||
class DenyStageView(StageView):
|
||||
"""Cancells the current flow"""
|
||||
"""Cancels the current flow"""
|
||||
|
||||
def get(self, request: HttpRequest) -> HttpResponse:
|
||||
"""Cancells the current flow"""
|
||||
"""Cancels the current flow"""
|
||||
return self.executor.stage_invalid()
|
||||
|
||||
def post(self, request: HttpRequest) -> HttpResponse:
|
||||
|
@ -6,6 +6,7 @@ from django.db import transaction
|
||||
from django.db.utils import IntegrityError, InternalError
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from authentik.core.middleware import SESSION_KEY_IMPERSONATE_USER
|
||||
from authentik.core.models import USER_ATTRIBUTE_SOURCES, User, UserSourceConnection
|
||||
@ -148,7 +149,11 @@ class UserWriteStageView(StageView):
|
||||
and SESSION_KEY_IMPERSONATE_USER not in self.request.session
|
||||
):
|
||||
should_update_session = True
|
||||
self.update_user(user)
|
||||
try:
|
||||
self.update_user(user)
|
||||
except ValidationError as exc:
|
||||
self.logger.warning("failed to update user", exc=exc)
|
||||
return self.executor.stage_invalid(_("Failed to update user. Please try again later."))
|
||||
# Extra check to prevent flows from saving a user with a blank username
|
||||
if user.username == "":
|
||||
self.logger.warning("Aborting write to empty username", user=user)
|
||||
@ -162,7 +167,7 @@ class UserWriteStageView(StageView):
|
||||
user.ak_groups.add(*self.executor.plan.context[PLAN_CONTEXT_GROUPS])
|
||||
except (IntegrityError, ValueError, TypeError, InternalError) as exc:
|
||||
self.logger.warning("Failed to save user", exc=exc)
|
||||
return self.executor.stage_invalid(_("Failed to save user"))
|
||||
return self.executor.stage_invalid(_("Failed to update user. Please try again later."))
|
||||
user_write.send(sender=self, request=request, user=user, data=data, created=user_created)
|
||||
# Check if the password has been updated, and update the session auth hash
|
||||
if should_update_session:
|
||||
|
@ -2560,6 +2560,42 @@
|
||||
"$ref": "#/$defs/model_authentik_core.token"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_blueprints.metaapplyblueprint"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_blueprints.metaapplyblueprint"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_blueprints.metaapplyblueprint"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -3852,8 +3888,7 @@
|
||||
},
|
||||
"required": [
|
||||
"username",
|
||||
"name",
|
||||
"groups"
|
||||
"name"
|
||||
],
|
||||
"title": "User"
|
||||
},
|
||||
@ -4044,8 +4079,7 @@
|
||||
},
|
||||
"required": [
|
||||
"username",
|
||||
"name",
|
||||
"groups"
|
||||
"name"
|
||||
],
|
||||
"title": "User"
|
||||
},
|
||||
@ -4240,8 +4274,7 @@
|
||||
},
|
||||
"required": [
|
||||
"username",
|
||||
"name",
|
||||
"groups"
|
||||
"name"
|
||||
],
|
||||
"title": "User"
|
||||
},
|
||||
@ -6383,8 +6416,7 @@
|
||||
},
|
||||
"required": [
|
||||
"username",
|
||||
"name",
|
||||
"groups"
|
||||
"name"
|
||||
],
|
||||
"title": "User"
|
||||
},
|
||||
@ -7119,8 +7151,7 @@
|
||||
},
|
||||
"required": [
|
||||
"username",
|
||||
"name",
|
||||
"groups"
|
||||
"name"
|
||||
],
|
||||
"title": "User"
|
||||
},
|
||||
@ -8314,6 +8345,21 @@
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_blueprints.metaapplyblueprint": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"identifiers": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Identifiers"
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean",
|
||||
"title": "Required"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ entries:
|
||||
|
||||
# photos supports URLs to images, however authentik might return data URIs
|
||||
avatar = request.user.avatar
|
||||
photos = []
|
||||
photos = None
|
||||
if "://" in avatar:
|
||||
photos = [{"value": avatar, "type": "photo"}]
|
||||
|
||||
@ -31,11 +31,11 @@ entries:
|
||||
|
||||
emails = []
|
||||
if request.user.email != "":
|
||||
emails.append({
|
||||
emails = [{
|
||||
"value": request.user.email,
|
||||
"type": "other",
|
||||
"primary": True,
|
||||
})
|
||||
}]
|
||||
return {
|
||||
"userName": request.user.username,
|
||||
"name": {
|
||||
|
@ -32,7 +32,7 @@ services:
|
||||
volumes:
|
||||
- redis:/data
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.4.1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.3}
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
@ -50,7 +50,7 @@ services:
|
||||
- "${COMPOSE_PORT_HTTP:-9000}:9000"
|
||||
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
|
||||
worker:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.4.1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.3}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
|
4
go.mod
4
go.mod
@ -23,10 +23,10 @@ require (
|
||||
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba
|
||||
github.com/pires/go-proxyproto v0.7.0
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/sirupsen/logrus v1.9.2
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
goauthentik.io/api/v3 v3.2023041.12
|
||||
goauthentik.io/api/v3 v3.2023050.2
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.8.0
|
||||
golang.org/x/sync v0.2.0
|
||||
|
8
go.sum
8
go.sum
@ -200,8 +200,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
|
||||
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
@ -241,8 +241,8 @@ go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvx
|
||||
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
|
||||
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
goauthentik.io/api/v3 v3.2023041.12 h1:lk8eCWYW/P8U4r10RgtIq2NyaAqZ3KKrKc7eierV6aY=
|
||||
goauthentik.io/api/v3 v3.2023041.12/go.mod h1:nYECml4jGbp/541hj8GcylKQG1gVBsKppHy4+7G8u4U=
|
||||
goauthentik.io/api/v3 v3.2023050.2 h1:EnwEaPM2qSFwfow0G/pTk9GHXmux0ldN77b+/gMeGTM=
|
||||
goauthentik.io/api/v3 v3.2023050.2/go.mod h1:nYECml4jGbp/541hj8GcylKQG1gVBsKppHy4+7G8u4U=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2023.4.1"
|
||||
const VERSION = "2023.5.3"
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-05-10 17:31+0000\n"
|
||||
"POT-Creation-Date: 2023-05-18 14:21+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"
|
||||
@ -1381,33 +1381,33 @@ msgstr ""
|
||||
msgid "SCIM Mappings"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:50
|
||||
#: authentik/providers/scim/tasks.py:52
|
||||
msgid "Starting full SCIM sync"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:57
|
||||
#: authentik/providers/scim/tasks.py:59
|
||||
#, python-format
|
||||
msgid "Syncing page %(page)d of users"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:61
|
||||
#: authentik/providers/scim/tasks.py:63
|
||||
#, python-format
|
||||
msgid "Syncing page %(page)d of groups"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:90
|
||||
#: authentik/providers/scim/tasks.py:92
|
||||
#, python-format
|
||||
msgid "Failed to sync user due to remote error %(name)s: %(error)s"
|
||||
msgid "Failed to sync user %(user_name)s due to remote error: %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:101 authentik/providers/scim/tasks.py:142
|
||||
#: authentik/providers/scim/tasks.py:103 authentik/providers/scim/tasks.py:144
|
||||
#, python-format
|
||||
msgid "Stopping sync due to error: %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/scim/tasks.py:131
|
||||
#: authentik/providers/scim/tasks.py:133
|
||||
#, python-format
|
||||
msgid "Failed to sync group due to remote error %(name)s: %(error)s"
|
||||
msgid "Failed to sync group %(group_name)s due to remote error: %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/recovery/management/commands/create_admin_group.py:11
|
||||
@ -2106,6 +2106,10 @@ msgid ""
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/identification/api.py:20
|
||||
msgid "When no user fields are selected, at least one source must be selected"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/identification/models.py:29
|
||||
msgid ""
|
||||
"Fields of the user object to match against. (Hold shift to select multiple "
|
||||
@ -2397,16 +2401,17 @@ msgstr ""
|
||||
msgid "User Write Stages"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/user_write/stage.py:132
|
||||
#: authentik/stages/user_write/stage.py:133
|
||||
msgid "No Pending data."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/user_write/stage.py:138
|
||||
#: authentik/stages/user_write/stage.py:139
|
||||
msgid "No user found and can't create new user."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/user_write/stage.py:165
|
||||
msgid "Failed to save user"
|
||||
#: authentik/stages/user_write/stage.py:156
|
||||
#: authentik/stages/user_write/stage.py:170
|
||||
msgid "Failed to update user. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/tenants/models.py:23
|
||||
|
160
poetry.lock
generated
160
poetry.lock
generated
@ -878,63 +878,63 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.2.5"
|
||||
version = "7.2.6"
|
||||
description = "Code coverage measurement for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"},
|
||||
{file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"},
|
||||
{file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"},
|
||||
{file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"},
|
||||
{file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"},
|
||||
{file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"},
|
||||
{file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"},
|
||||
{file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-win32.whl", hash = "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec"},
|
||||
{file = "coverage-7.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-win32.whl", hash = "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b"},
|
||||
{file = "coverage-7.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-win32.whl", hash = "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473"},
|
||||
{file = "coverage-7.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-win32.whl", hash = "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5"},
|
||||
{file = "coverage-7.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-win32.whl", hash = "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb"},
|
||||
{file = "coverage-7.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783"},
|
||||
{file = "coverage-7.2.6-pp37.pp38.pp39-none-any.whl", hash = "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d"},
|
||||
{file = "coverage-7.2.6.tar.gz", hash = "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -988,14 +988,13 @@ tox = ["tox"]
|
||||
|
||||
[[package]]
|
||||
name = "dacite"
|
||||
version = "1.8.0"
|
||||
version = "1.8.1"
|
||||
description = "Simple creation of data classes from dictionaries."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "dacite-1.8.0-py3-none-any.whl", hash = "sha256:f7b1205cc5d9b62835aac8cbc1e6e37c1da862359a401f1edbe2ae08fbdc6193"},
|
||||
{file = "dacite-1.8.0.tar.gz", hash = "sha256:6257a5e505b61a8cafee7ef3ad08cf32ee9b885718f42395d017e0a9b4c6af65"},
|
||||
{file = "dacite-1.8.1-py3-none-any.whl", hash = "sha256:cc31ad6fdea1f49962ea42db9421772afe01ac5442380d9a99fcf3d188c61afe"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -1252,14 +1251,14 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "docker"
|
||||
version = "6.1.1"
|
||||
version = "6.1.2"
|
||||
description = "A Python library for the Docker Engine API."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "docker-6.1.1-py3-none-any.whl", hash = "sha256:8308b23d3d0982c74f7aa0a3abd774898c0c4fba006e9c3bde4f68354e470fe2"},
|
||||
{file = "docker-6.1.1.tar.gz", hash = "sha256:5ec18b9c49d48ee145a5b5824bb126dc32fc77931e18444783fc07a7724badc0"},
|
||||
{file = "docker-6.1.2-py3-none-any.whl", hash = "sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e"},
|
||||
{file = "docker-6.1.2.tar.gz", hash = "sha256:dcc088adc2ec4e7cfc594e275d8bd2c9738c56c808de97476939ef67db5af8c2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -3109,29 +3108,29 @@ pyasn1 = ">=0.1.3"
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.265"
|
||||
version = "0.0.267"
|
||||
description = "An extremely fast Python linter, written in Rust."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.0.265-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:30ddfe22de6ce4eb1260408f4480bbbce998f954dbf470228a21a9b2c45955e4"},
|
||||
{file = "ruff-0.0.265-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:a11bd0889e88d3342e7bc514554bb4461bf6cc30ec115821c2425cfaac0b1b6a"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a9b38bdb40a998cbc677db55b6225a6c4fadcf8819eb30695e1b8470942426b"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8b44a245b60512403a6a03a5b5212da274d33862225c5eed3bcf12037eb19bb"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b279fa55ea175ef953208a6d8bfbcdcffac1c39b38cdb8c2bfafe9222add70bb"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5028950f7af9b119d43d91b215d5044976e43b96a0d1458d193ef0dd3c587bf8"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4057eb539a1d88eb84e9f6a36e0a999e0f261ed850ae5d5817e68968e7b89ed9"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d586e69ab5cbf521a1910b733412a5735936f6a610d805b89d35b6647e2a66aa"},
|
||||
{file = "ruff-0.0.265-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa17b13cd3f29fc57d06bf34c31f21d043735cc9a681203d634549b0e41047d1"},
|
||||
{file = "ruff-0.0.265-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:9ac13b11d9ad3001de9d637974ec5402a67cefdf9fffc3929ab44c2fcbb850a1"},
|
||||
{file = "ruff-0.0.265-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:62a9578b48cfd292c64ea3d28681dc16b1aa7445b7a7709a2884510fc0822118"},
|
||||
{file = "ruff-0.0.265-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0f9967f84da42d28e3d9d9354cc1575f96ed69e6e40a7d4b780a7a0418d9409"},
|
||||
{file = "ruff-0.0.265-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1d5a8de2fbaf91ea5699451a06f4074e7a312accfa774ad9327cde3e4fda2081"},
|
||||
{file = "ruff-0.0.265-py3-none-win32.whl", hash = "sha256:9e9db5ccb810742d621f93272e3cc23b5f277d8d00c4a79668835d26ccbe48dd"},
|
||||
{file = "ruff-0.0.265-py3-none-win_amd64.whl", hash = "sha256:f54facf286103006171a00ce20388d88ed1d6732db3b49c11feb9bf3d46f90e9"},
|
||||
{file = "ruff-0.0.265-py3-none-win_arm64.whl", hash = "sha256:c78470656e33d32ddc54e8482b1b0fc6de58f1195586731e5ff1405d74421499"},
|
||||
{file = "ruff-0.0.265.tar.gz", hash = "sha256:53c17f0dab19ddc22b254b087d1381b601b155acfa8feed514f0d6a413d0ab3a"},
|
||||
{file = "ruff-0.0.267-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:4adbbbe314d8fcc539a245065bad89446a3cef2e0c9cf70bf7bb9ed6fe31856d"},
|
||||
{file = "ruff-0.0.267-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:67254ae34c38cba109fdc52e4a70887de1f850fb3971e5eeef343db67305d1c1"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbe104f21a429b77eb5ac276bd5352fd8c0e1fbb580b4c772f77ee8c76825654"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:db33deef2a5e1cf528ca51cc59dd764122a48a19a6c776283b223d147041153f"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9adf1307fa9d840d1acaa477eb04f9702032a483214c409fca9dc46f5f157fe3"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0afca3633c8e2b6c0a48ad0061180b641b3b404d68d7e6736aab301c8024c424"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2972241065b1c911bce3db808837ed10f4f6f8a8e15520a4242d291083605ab6"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f731d81cb939e757b0335b0090f18ca2e9ff8bcc8e6a1cf909245958949b6e11"},
|
||||
{file = "ruff-0.0.267-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20c594eb56c19063ef5a57f89340e64c6550e169d6a29408a45130a8c3068adc"},
|
||||
{file = "ruff-0.0.267-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:45d61a2b01bdf61581a2ee039503a08aa603dc74a6bbe6fb5d1ce3052f5370e5"},
|
||||
{file = "ruff-0.0.267-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2107cec3699ca4d7bd41543dc1d475c97ae3a21ea9212238b5c2088fa8ee7722"},
|
||||
{file = "ruff-0.0.267-py3-none-musllinux_1_2_i686.whl", hash = "sha256:786de30723c71fc46b80a173c3313fc0dbe73c96bd9da8dd1212cbc2f84cdfb2"},
|
||||
{file = "ruff-0.0.267-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a898953949e37c109dd242cfcf9841e065319995ebb7cdfd213b446094a942f"},
|
||||
{file = "ruff-0.0.267-py3-none-win32.whl", hash = "sha256:d12ab329474c46b96d962e2bdb92e3ad2144981fe41b89c7770f370646c0101f"},
|
||||
{file = "ruff-0.0.267-py3-none-win_amd64.whl", hash = "sha256:d09aecc9f5845586ba90911d815f9772c5a6dcf2e34be58c6017ecb124534ac4"},
|
||||
{file = "ruff-0.0.267-py3-none-win_arm64.whl", hash = "sha256:7df7eb5f8d791566ba97cc0b144981b9c080a5b861abaf4bb35a26c8a77b83e9"},
|
||||
{file = "ruff-0.0.267.tar.gz", hash = "sha256:632cec7bbaf3c06fcf0a72a1dd029b7d8b7f424ba95a574aaa135f5d20a00af7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3154,14 +3153,14 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]}
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.22.2"
|
||||
version = "1.23.1"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "sentry-sdk-1.22.2.tar.gz", hash = "sha256:5932c092c6e6035584eb74d77064e4bce3b7935dfc4a331349719a40db265840"},
|
||||
{file = "sentry_sdk-1.22.2-py2.py3-none-any.whl", hash = "sha256:cf89a5063ef84278d186aceaed6fb595bfe67d099298e537634a323664265669"},
|
||||
{file = "sentry-sdk-1.23.1.tar.gz", hash = "sha256:0300fbe7a07b3865b3885929fb863a68ff01f59e3bcfb4e7953d0bf7fd19c67f"},
|
||||
{file = "sentry_sdk-1.23.1-py2.py3-none-any.whl", hash = "sha256:a884e2478e0b055776ea2b9234d5de9339b4bae0b3a5e74ae43d131db8ded27e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -3178,10 +3177,11 @@ chalice = ["chalice (>=1.16.0)"]
|
||||
django = ["django (>=1.8)"]
|
||||
falcon = ["falcon (>=1.4)"]
|
||||
fastapi = ["fastapi (>=0.79.0)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
|
||||
grpcio = ["grpcio (>=1.21.1)"]
|
||||
httpx = ["httpx (>=0.16.0)"]
|
||||
huey = ["huey (>=2)"]
|
||||
loguru = ["loguru (>=0.5)"]
|
||||
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
|
||||
pure-eval = ["asttokens", "executing", "pure-eval"]
|
||||
pymongo = ["pymongo (>=3.1)"]
|
||||
|
@ -4,7 +4,8 @@ FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
|
||||
COPY ./web /static/
|
||||
|
||||
ENV NODE_ENV=production
|
||||
RUN cd /static && npm ci && npm run build-proxy
|
||||
WORKDIR /static
|
||||
RUN npm ci --include=dev && npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM docker.io/golang:1.20.4-bullseye AS builder
|
||||
|
@ -113,7 +113,7 @@ filterwarnings = [
|
||||
|
||||
[tool.poetry]
|
||||
name = "authentik"
|
||||
version = "2023.4.1"
|
||||
version = "2023.5.3"
|
||||
description = ""
|
||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||
|
||||
|
18
schema.yml
18
schema.yml
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2023.4.1
|
||||
version: 2023.5.3
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@goauthentik.io
|
||||
@ -38956,6 +38956,11 @@ components:
|
||||
shared_secret:
|
||||
type: string
|
||||
description: Shared secret between clients and server to hash packets.
|
||||
outpost_set:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
readOnly: true
|
||||
required:
|
||||
- assigned_application_name
|
||||
- assigned_application_slug
|
||||
@ -38965,6 +38970,7 @@ components:
|
||||
- component
|
||||
- meta_model_name
|
||||
- name
|
||||
- outpost_set
|
||||
- pk
|
||||
- verbose_name
|
||||
- verbose_name_plural
|
||||
@ -39824,11 +39830,11 @@ components:
|
||||
type: string
|
||||
description: Get object component so that we know how to edit the object
|
||||
readOnly: true
|
||||
assigned_application_slug:
|
||||
assigned_backchannel_application_slug:
|
||||
type: string
|
||||
description: Internal application name, used in URLs.
|
||||
readOnly: true
|
||||
assigned_application_name:
|
||||
assigned_backchannel_application_name:
|
||||
type: string
|
||||
description: Application's display Name.
|
||||
readOnly: true
|
||||
@ -39857,8 +39863,8 @@ components:
|
||||
format: uuid
|
||||
nullable: true
|
||||
required:
|
||||
- assigned_application_name
|
||||
- assigned_application_slug
|
||||
- assigned_backchannel_application_name
|
||||
- assigned_backchannel_application_slug
|
||||
- component
|
||||
- meta_model_name
|
||||
- name
|
||||
@ -40971,7 +40977,6 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- avatar
|
||||
- groups
|
||||
- groups_obj
|
||||
- is_superuser
|
||||
- name
|
||||
@ -41429,7 +41434,6 @@ components:
|
||||
type: string
|
||||
minLength: 1
|
||||
required:
|
||||
- groups
|
||||
- name
|
||||
- username
|
||||
UserSAMLSourceConnection:
|
||||
|
@ -243,7 +243,7 @@ class TestSourceOAuth1(SeleniumTestCase):
|
||||
|
||||
def get_container_specs(self) -> Optional[dict[str, Any]]:
|
||||
return {
|
||||
"image": "ghcr.io/beryju/oauth1-test-server:latest",
|
||||
"image": "ghcr.io/beryju/oauth1-test-server:v1.1",
|
||||
"detach": True,
|
||||
"network_mode": "host",
|
||||
"auto_remove": True,
|
||||
|
1408
web/package-lock.json
generated
1408
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -16,45 +16,24 @@
|
||||
"background-image": "npx @squoosh/cli -d src/assets/images --resize '{\"enabled\":true,\"width\":2560,\"method\":\"lanczos3\",\"fitMethod\":\"contain\",\"premultiply\":true,\"linearRGB\":true}' --mozjpeg '{\"quality\":75,\"baseline\":false,\"arithmetic\":false,\"progressive\":true,\"optimize_coding\":true,\"smoothing\":0,\"color_space\":3,\"quant_table\":3,\"trellis_multipass\":false,\"trellis_opt_zero\":false,\"trellis_opt_table\":false,\"trellis_loops\":1,\"auto_subsample\":true,\"chroma_subsample\":2,\"separate_chroma_quality\":false,\"chroma_quality\":75}' src/assets/images/flow_background.jpg"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.21.8",
|
||||
"@babel/plugin-proposal-decorators": "^7.21.0",
|
||||
"@babel/plugin-transform-runtime": "^7.21.4",
|
||||
"@babel/preset-env": "^7.21.5",
|
||||
"@babel/preset-typescript": "^7.21.5",
|
||||
"@codemirror/lang-html": "^6.4.3",
|
||||
"@codemirror/lang-javascript": "^6.1.7",
|
||||
"@codemirror/lang-javascript": "^6.1.8",
|
||||
"@codemirror/lang-python": "^6.1.2",
|
||||
"@codemirror/lang-xml": "^6.0.2",
|
||||
"@codemirror/legacy-modes": "^6.3.2",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.2.2",
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@goauthentik/api": "^2023.4.1-1683802980",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
|
||||
"@lingui/cli": "^4.0.0",
|
||||
"@lingui/core": "^4.0.0",
|
||||
"@lingui/detect-locale": "^4.0.0",
|
||||
"@lingui/format-po-gettext": "^4.0.0",
|
||||
"@lingui/macro": "^4.0.0",
|
||||
"@goauthentik/api": "^2023.5.0-1684333401",
|
||||
"@lingui/cli": "^4.1.2",
|
||||
"@lingui/core": "^4.1.2",
|
||||
"@lingui/detect-locale": "^4.1.2",
|
||||
"@lingui/format-po-gettext": "^4.1.2",
|
||||
"@lingui/macro": "^4.1.2",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^24.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-typescript": "^11.1.0",
|
||||
"@sentry/browser": "^7.51.2",
|
||||
"@sentry/tracing": "^7.51.2",
|
||||
"@squoosh/cli": "^0.7.3",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
||||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "5.60.7",
|
||||
"@types/grecaptcha": "^3.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.5",
|
||||
"@typescript-eslint/parser": "^5.59.5",
|
||||
"@sentry/browser": "^7.52.1",
|
||||
"@sentry/tracing": "^7.52.1",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.3.0",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
@ -62,27 +41,49 @@
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.30.2",
|
||||
"country-flag-icons": "^1.5.7",
|
||||
"fuse.js": "^6.6.2",
|
||||
"lit": "^2.7.4",
|
||||
"mermaid": "^10.1.0",
|
||||
"rapidoc": "^9.3.4",
|
||||
"webcomponent-qr-code": "^1.1.1",
|
||||
"yaml": "^2.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.8",
|
||||
"@babel/plugin-proposal-decorators": "^7.21.0",
|
||||
"@babel/plugin-transform-runtime": "^7.21.4",
|
||||
"@babel/preset-env": "^7.21.5",
|
||||
"@babel/preset-typescript": "^7.21.5",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^25.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-typescript": "^11.1.1",
|
||||
"@squoosh/cli": "^0.7.3",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
||||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "5.60.7",
|
||||
"@types/grecaptcha": "^3.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
||||
"@typescript-eslint/parser": "^5.59.6",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-custom-elements": "0.0.8",
|
||||
"eslint-plugin-lit": "^1.8.3",
|
||||
"fuse.js": "^6.6.2",
|
||||
"lit": "^2.7.4",
|
||||
"mermaid": "^10.1.0",
|
||||
"moment": "^2.29.4",
|
||||
"prettier": "^2.8.8",
|
||||
"pyright": "^1.1.307",
|
||||
"rapidoc": "^9.3.4",
|
||||
"pyright": "^1.1.308",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-cssimport": "^1.0.3",
|
||||
"rollup-plugin-minify-html-literals": "^1.2.6",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-lit-plugin": "^1.2.1",
|
||||
"tslib": "^2.5.0",
|
||||
"tslib": "^2.5.1",
|
||||
"turnstile-types": "^1.1.2",
|
||||
"typescript": "^5.0.4",
|
||||
"webcomponent-qr-code": "^1.1.1",
|
||||
"yaml": "^2.2.2"
|
||||
"typescript": "^5.0.4"
|
||||
}
|
||||
}
|
||||
|
@ -191,8 +191,12 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
||||
const selected = Array.from(this.instance?.providers || []).some((sp) => {
|
||||
return sp == provider.pk;
|
||||
});
|
||||
let appName = provider.assignedApplicationName;
|
||||
if (provider.assignedBackchannelApplicationName) {
|
||||
appName = provider.assignedBackchannelApplicationName;
|
||||
}
|
||||
return html`<option value=${ifDefined(provider.pk)} ?selected=${selected}>
|
||||
${provider.assignedApplicationName} (${provider.name})
|
||||
${appName} (${provider.name})
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
|
@ -61,6 +61,10 @@ export class ProviderViewPage extends AKElement {
|
||||
return html`<ak-provider-scim-view
|
||||
providerID=${ifDefined(this.provider.pk)}
|
||||
></ak-provider-scim-view>`;
|
||||
case "ak-provider-radius-form":
|
||||
return html`<ak-provider-radius-view
|
||||
providerID=${ifDefined(this.provider.pk)}
|
||||
></ak-provider-radius-view>`;
|
||||
default:
|
||||
return html`<p>Invalid provider type ${this.provider?.component}</p>`;
|
||||
}
|
||||
|
@ -79,6 +79,11 @@ export class RadiusProviderViewPage extends AKElement {
|
||||
data-tab-title="${t`Overview`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${this.provider?.outpostSet.length < 1
|
||||
? html`<div slot="header" class="pf-c-banner pf-m-warning">
|
||||
${t`Warning: Provider is not used by any Outpost.`}
|
||||
</div>`
|
||||
: html``}
|
||||
<div class="pf-u-display-flex pf-u-justify-content-center">
|
||||
<div class="pf-u-w-75">
|
||||
<div class="pf-c-card">
|
||||
@ -152,7 +157,7 @@ export class RadiusProviderViewPage extends AKElement {
|
||||
<ak-object-changelog
|
||||
targetModelPk=${this.provider.pk || ""}
|
||||
targetModelApp="authentik_providers_radius"
|
||||
targetModelName="RadiusProvider"
|
||||
targetModelName="radiusprovider"
|
||||
>
|
||||
</ak-object-changelog>
|
||||
</div>
|
||||
|
@ -121,9 +121,14 @@ export class SCIMProviderViewPage extends AKElement {
|
||||
if (!this.provider) {
|
||||
return html``;
|
||||
}
|
||||
return html` <div slot="header" class="pf-c-banner pf-m-info">
|
||||
return html`<div slot="header" class="pf-c-banner pf-m-info">
|
||||
${t`SCIM provider is in preview.`}
|
||||
</div>
|
||||
${!this.provider?.assignedBackchannelApplicationName
|
||||
? html`<div slot="header" class="pf-c-banner pf-m-warning">
|
||||
${t`Warning: Provider is not assigned to an application as backchannel provider.`}
|
||||
</div>`
|
||||
: html``}
|
||||
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
|
||||
<div class="pf-l-grid__item pf-m-7-col pf-l-stack pf-m-gutter">
|
||||
<div class="pf-c-card pf-m-12-col pf-l-stack__item">
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 551 KiB After Width: | Height: | Size: 399 KiB |
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
||||
export const ERROR_CLASS = "pf-m-danger";
|
||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||
export const CURRENT_CLASS = "pf-m-current";
|
||||
export const VERSION = "2023.4.1";
|
||||
export const VERSION = "2023.5.3";
|
||||
export const TITLE_DEFAULT = "authentik";
|
||||
export const ROUTE_SEPARATOR = ";";
|
||||
|
||||
|
@ -142,6 +142,10 @@ export abstract class Form<T> extends AKElement {
|
||||
if (element.hidden || !inputElement) {
|
||||
return;
|
||||
}
|
||||
// Skip elements that are writeOnly where the user hasn't clicked on the value
|
||||
if (element.writeOnly && !element.writeOnlyActivated) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
inputElement.tagName.toLowerCase() === "select" &&
|
||||
"multiple" in inputElement.attributes
|
||||
|
@ -525,8 +525,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
${this.flowInfo?.background?.startsWith("/static")
|
||||
? html`
|
||||
<li>
|
||||
<a
|
||||
href="https://unsplash.com/@clarissemeyer"
|
||||
<a href="https://unsplash.com/@joshnh"
|
||||
>${t`Background image`}</a
|
||||
>
|
||||
</li>
|
||||
|
@ -39,10 +39,7 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
|
||||
}
|
||||
|
||||
getURL(): string {
|
||||
if (!this.challenge.to.includes("://")) {
|
||||
return window.location.origin + this.challenge.to;
|
||||
}
|
||||
return this.challenge.to;
|
||||
return new URL(this.challenge.to, document.baseURI).toString();
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
|
@ -53,9 +53,10 @@ export class AuthenticatorValidateStage
|
||||
_selectedDeviceChallenge?: DeviceChallenge;
|
||||
|
||||
set selectedDeviceChallenge(value: DeviceChallenge | undefined) {
|
||||
const previousChallenge = this._selectedDeviceChallenge;
|
||||
this._selectedDeviceChallenge = value;
|
||||
if (!value) return;
|
||||
if (value === this._selectedDeviceChallenge) return;
|
||||
if (value === previousChallenge) return;
|
||||
// We don't use this.submit here, as we don't want to advance the flow.
|
||||
// We just want to notify the backend which challenge has been selected.
|
||||
new FlowsApi(DEFAULT_CONFIG).flowsExecutorSolve({
|
||||
@ -134,7 +135,7 @@ export class AuthenticatorValidateStage
|
||||
<small>${t`In case you can't access any other method.`}</small>
|
||||
</div>`;
|
||||
case DeviceClassesEnum.Sms:
|
||||
return html`<i class="fas fa-mobile"></i>
|
||||
return html`<i class="fas fa-mobile-alt"></i>
|
||||
<div class="right">
|
||||
<p>${t`SMS`}</p>
|
||||
<small>${t`Tokens sent via SMS.`}</small>
|
||||
|
@ -7,7 +7,7 @@ import { PasswordManagerPrefill } from "@goauthentik/flow/stages/identification/
|
||||
|
||||
import { t } from "@lingui/macro";
|
||||
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
@ -37,7 +37,24 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
|
||||
showBackButton = false;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton];
|
||||
return [
|
||||
PFBase,
|
||||
PFLogin,
|
||||
PFForm,
|
||||
PFFormControl,
|
||||
PFTitle,
|
||||
PFButton,
|
||||
css`
|
||||
.icon-description {
|
||||
display: flex;
|
||||
}
|
||||
.icon-description i {
|
||||
font-size: 2em;
|
||||
padding: 0.25em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
@ -62,13 +79,23 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
|
||||
? html`<p>${t`A code has been sent to you via SMS.`}</p>`
|
||||
: html``}
|
||||
<div class="icon-description">
|
||||
<i
|
||||
class="fa ${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
|
||||
? "fa-key"
|
||||
: "fa-mobile-alt"}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
|
||||
? html`<p>${t`A code has been sent to you via SMS.`}</p>`
|
||||
: html`<p>
|
||||
${t`Open your two-factor authenticator app to view your authentication code.`}
|
||||
</p>`}
|
||||
</div>
|
||||
<ak-form-element
|
||||
label="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
|
||||
? t`Static token`
|
||||
: t`Code`}"
|
||||
: t`Authentication code`}"
|
||||
?required="${true}"
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {})["code"]}
|
||||
@ -85,7 +112,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
|
||||
DeviceClassesEnum.Static
|
||||
? "[0-9a-zA-Z]*"
|
||||
: "[0-9]*"}"
|
||||
placeholder="${t`Please enter your Code`}"
|
||||
placeholder="${t`Please enter your code`}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
|
@ -420,7 +420,7 @@ msgstr "Erweiterte Einstellungen"
|
||||
msgid "Affected model:"
|
||||
msgstr "Betroffenes Modell:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alarm"
|
||||
|
||||
@ -791,6 +791,10 @@ msgstr "Authentifizierung mit Plex..."
|
||||
msgid "Authentication"
|
||||
msgstr "Authentifizierung"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1423,7 +1427,6 @@ msgstr "Schließen"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Code"
|
||||
|
||||
@ -4382,7 +4385,7 @@ msgstr "Nicht Sie?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Hinweis"
|
||||
|
||||
@ -4554,6 +4557,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr "Einstellungen öffnen"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "OpenID-Konfigurations-Aussteller"
|
||||
@ -4827,8 +4834,11 @@ msgstr "History"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Bitte geben Sie Ihren Code ein "
|
||||
|
||||
@ -7160,8 +7170,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7814,7 +7824,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Warnung"
|
||||
@ -7839,6 +7849,10 @@ msgstr "Warnung: Keine Einladungsphase ist an einen Ablauf gebunden. Einladungen
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Warnung: Keine Richtlinie zugewiesen"
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7847,6 +7861,7 @@ msgstr "Warnung: Der Anbieter wird nicht von einer Anwendung verwendet."
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Warnung: Der Anbieter wird von keinem Outpost verwendet."
|
||||
|
||||
|
@ -401,7 +401,7 @@ msgstr "Advanced settings"
|
||||
msgid "Affected model:"
|
||||
msgstr "Affected model:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alert"
|
||||
|
||||
@ -776,6 +776,10 @@ msgstr "Authenticating with Plex..."
|
||||
msgid "Authentication"
|
||||
msgstr "Authentication"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr "Authentication code"
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1420,7 +1424,6 @@ msgstr "Close"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Code"
|
||||
|
||||
@ -4444,7 +4447,7 @@ msgstr "Not you?"
|
||||
msgid "Notes"
|
||||
msgstr "Notes"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Notice"
|
||||
|
||||
@ -4624,6 +4627,10 @@ msgstr "Open login"
|
||||
msgid "Open settings"
|
||||
msgstr "Open settings"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr "Open your two-factor authenticator app to view your authentication code."
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "OpenID Configuration Issuer"
|
||||
@ -4919,8 +4926,11 @@ msgstr "Plan history"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr "Please enter the code you received via SMS"
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr "Please enter your code"
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Please enter your Code"
|
||||
|
||||
@ -7318,8 +7328,8 @@ msgstr "Unknown provider type"
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr "Unknown proxy mode"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr "Unknown severity"
|
||||
|
||||
@ -7980,7 +7990,7 @@ msgstr "Waiting for authentication..."
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Warning"
|
||||
@ -8005,6 +8015,10 @@ msgstr "Warning: No invitation stage is bound to any flow. Invitations will not
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Warning: Policy is not assigned."
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -8013,6 +8027,7 @@ msgstr "Warning: Provider is not used by an Application."
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Warning: Provider is not used by any Outpost."
|
||||
|
||||
|
@ -398,7 +398,7 @@ msgstr "Configuraciones avanzadas"
|
||||
msgid "Affected model:"
|
||||
msgstr "Modelo afectado:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alerta"
|
||||
|
||||
@ -769,6 +769,10 @@ msgstr "Autenticando con Plex..."
|
||||
msgid "Authentication"
|
||||
msgstr "Autenticación"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1399,7 +1403,6 @@ msgstr "Cerrar"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Código"
|
||||
|
||||
@ -4358,7 +4361,7 @@ msgstr "¿No eres tú?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Notificación"
|
||||
|
||||
@ -4530,6 +4533,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "Emisor de configuración de OpenID"
|
||||
@ -4803,8 +4810,11 @@ msgstr "Historial del plan"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Por favor, introduzca su código"
|
||||
|
||||
@ -7136,8 +7146,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7790,7 +7800,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Aviso"
|
||||
@ -7815,6 +7825,10 @@ msgstr "Advertencia: ninguna etapa de invitación está vinculada a ningún fluj
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Advertencia: la política no está asignada."
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7823,6 +7837,7 @@ msgstr "Advertencia: Una aplicación no utiliza el proveedor."
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Advertencia: ningún puesto avanzado utiliza el proveedor."
|
||||
|
||||
|
@ -403,7 +403,7 @@ msgstr "Paramètres avancés"
|
||||
msgid "Affected model:"
|
||||
msgstr "Modèle affecté :"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alerte"
|
||||
|
||||
@ -774,6 +774,10 @@ msgstr "Authentification avec Plex..."
|
||||
msgid "Authentication"
|
||||
msgstr "Authentification"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1404,7 +1408,6 @@ msgstr "Fermer"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Code"
|
||||
|
||||
@ -4359,7 +4362,7 @@ msgstr "Pas vous ?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Note"
|
||||
|
||||
@ -4531,6 +4534,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr "Ouvrir les paramètres"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "Émetteur de la configuration OpenID"
|
||||
@ -4804,8 +4811,11 @@ msgstr "Historique du plan"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Entrez votre code"
|
||||
|
||||
@ -7127,8 +7137,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7781,7 +7791,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Avertissement"
|
||||
@ -7806,6 +7816,10 @@ msgstr "Attention : aucune étape d’invitation n’a été ajoutée à aucun f
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Avertissement : la politique n'est pas assignée."
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7814,6 +7828,7 @@ msgstr ""
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Attention : ce fournisseur n’est utilisé par aucun avant-poste."
|
||||
|
||||
|
@ -402,7 +402,7 @@ msgstr "Zaawansowane ustawienia"
|
||||
msgid "Affected model:"
|
||||
msgstr "Model, którego dotyczy problem:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alert"
|
||||
|
||||
@ -773,6 +773,10 @@ msgstr "Uwierzytelnianie z Plex..."
|
||||
msgid "Authentication"
|
||||
msgstr "Uwierzytelnianie"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1405,7 +1409,6 @@ msgstr "Zamknij"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Kod"
|
||||
|
||||
@ -4366,7 +4369,7 @@ msgstr "Nie ty?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Uwaga"
|
||||
|
||||
@ -4538,6 +4541,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr "Otwórz ustawienia"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "Wystawca konfiguracji OpenID"
|
||||
@ -4811,8 +4818,11 @@ msgstr "Historia planu"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Wprowadź swój kod"
|
||||
|
||||
@ -7146,8 +7156,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7800,7 +7810,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Ostrzeżenie"
|
||||
@ -7825,6 +7835,10 @@ msgstr "Ostrzeżenie: żaden etap zaproszenia nie jest powiązany z żadnym prze
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Ostrzeżenie: zasada nie jest przypisana."
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7833,6 +7847,7 @@ msgstr "Ostrzeżenie: Dostawca nie jest używany przez aplikację."
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Ostrzeżenie: Dostawca nie jest używany przez żadną placówkę."
|
||||
|
||||
|
@ -397,7 +397,7 @@ msgstr ""
|
||||
msgid "Affected model:"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr ""
|
||||
|
||||
@ -768,6 +768,10 @@ msgstr ""
|
||||
msgid "Authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1408,7 +1412,6 @@ msgstr ""
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
@ -4423,7 +4426,7 @@ msgstr ""
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr ""
|
||||
|
||||
@ -4603,6 +4606,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr ""
|
||||
@ -4889,8 +4896,11 @@ msgstr ""
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr ""
|
||||
|
||||
@ -7276,8 +7286,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7938,7 +7948,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
@ -7963,6 +7973,10 @@ msgstr ""
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7971,6 +7985,7 @@ msgstr ""
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr ""
|
||||
|
||||
|
@ -398,7 +398,7 @@ msgstr "Gelişmiş ayarlar"
|
||||
msgid "Affected model:"
|
||||
msgstr "Etkilenen model:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alarm"
|
||||
|
||||
@ -769,6 +769,10 @@ msgstr "Plex ile kimlik doğrulaması..."
|
||||
msgid "Authentication"
|
||||
msgstr "Kimlik Doğrulama"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1399,7 +1403,6 @@ msgstr "Kapat"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "Kodu"
|
||||
|
||||
@ -4358,7 +4361,7 @@ msgstr "Sen değil mi?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "Uyarı"
|
||||
|
||||
@ -4530,6 +4533,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "OpenID Yapılandırması Yayımlayıcı"
|
||||
@ -4803,8 +4810,11 @@ msgstr "Plan geçmişi"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "Lütfen Kodunuzu girin"
|
||||
|
||||
@ -7136,8 +7146,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7790,7 +7800,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Uyarı"
|
||||
@ -7815,6 +7825,10 @@ msgstr "Uyarı: Hiçbir davetiye aşaması herhangi bir akışa bağlı değildi
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "Uyarı: İlke atanmamış."
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7823,6 +7837,7 @@ msgstr "Uyarı: Sağlayıcı bir Uygulama tarafından kullanılmaz."
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "Uyarı: Sağlayıcı herhangi bir Üs tarafından kullanılmaz."
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -404,7 +404,7 @@ msgstr "高级设置"
|
||||
msgid "Affected model:"
|
||||
msgstr "受影响的模型:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "注意"
|
||||
|
||||
@ -775,6 +775,10 @@ msgstr "正在使用 Plex 进行身份验证..."
|
||||
msgid "Authentication"
|
||||
msgstr "身份验证"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1407,7 +1411,6 @@ msgstr "关闭"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "代码"
|
||||
|
||||
@ -4366,7 +4369,7 @@ msgstr "不是你?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "注意"
|
||||
|
||||
@ -4538,6 +4541,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr "打开设置"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "OpenID 配置发行者"
|
||||
@ -4811,8 +4818,11 @@ msgstr "计划历史记录"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "请输入您的验证码"
|
||||
|
||||
@ -7144,8 +7154,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7798,7 +7808,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
@ -7823,6 +7833,10 @@ msgstr "警告:没有邀请阶段绑定到任何流程。邀请将无法按预
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "警告:策略未分配。"
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7831,6 +7845,7 @@ msgstr "警告:应用程序不使用提供程序。"
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "警告:提供者未被任何 Outpos 使用。"
|
||||
|
||||
|
@ -404,7 +404,7 @@ msgstr "高级设置"
|
||||
msgid "Affected model:"
|
||||
msgstr "受影响的模型:"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Alert"
|
||||
msgstr "注意"
|
||||
|
||||
@ -775,6 +775,10 @@ msgstr "正在使用 Plex 进行身份验证..."
|
||||
msgid "Authentication"
|
||||
msgstr "身份验证"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/admin/providers/radius/RadiusProviderForm.ts
|
||||
@ -1407,7 +1411,6 @@ msgstr "关闭"
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_sms/AuthenticatorSMSStage.ts
|
||||
#: src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Code"
|
||||
msgstr "代码"
|
||||
|
||||
@ -4366,7 +4369,7 @@ msgstr "不是你?"
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Notice"
|
||||
msgstr "注意"
|
||||
|
||||
@ -4538,6 +4541,10 @@ msgstr ""
|
||||
msgid "Open settings"
|
||||
msgstr "打开设置"
|
||||
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Open your two-factor authenticator app to view your authentication code."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
msgid "OpenID Configuration Issuer"
|
||||
msgstr "OpenID 配置发行者"
|
||||
@ -4811,8 +4818,11 @@ msgstr "计划历史记录"
|
||||
msgid "Please enter the code you received via SMS"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
#: src/flow/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "Please enter your code"
|
||||
msgstr ""
|
||||
|
||||
#: src/flow/providers/oauth2/DeviceCode.ts
|
||||
msgid "Please enter your Code"
|
||||
msgstr "请输入您的验证码"
|
||||
|
||||
@ -7144,8 +7154,8 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/events/utils.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
@ -7798,7 +7808,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/utils.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
@ -7823,6 +7833,10 @@ msgstr "警告:没有邀请阶段绑定到任何流程。邀请将无法按预
|
||||
msgid "Warning: Policy is not assigned."
|
||||
msgstr "警告:策略未分配。"
|
||||
|
||||
#: src/admin/providers/scim/SCIMProviderViewPage.ts
|
||||
msgid "Warning: Provider is not assigned to an application as backchannel provider."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/oauth2/OAuth2ProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/saml/SAMLProviderViewPage.ts
|
||||
@ -7831,6 +7845,7 @@ msgstr "警告:应用程序不使用提供程序。"
|
||||
|
||||
#: src/admin/providers/ldap/LDAPProviderViewPage.ts
|
||||
#: src/admin/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/admin/providers/radius/RadiusProviderViewPage.ts
|
||||
msgid "Warning: Provider is not used by any Outpost."
|
||||
msgstr "警告:提供者未被任何 Outpos 使用。"
|
||||
|
||||
|
@ -75,9 +75,9 @@ export class UserSettingsPage extends AKElement {
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
const pwStage = this.userSettings?.filter(
|
||||
(stage) => stage.component === "ak-user-settings-password",
|
||||
);
|
||||
const pwStage =
|
||||
this.userSettings?.filter((stage) => stage.component === "ak-user-settings-password") ||
|
||||
[];
|
||||
return html`<div class="pf-c-page">
|
||||
<main role="main" class="pf-c-page__main" tabindex="-1">
|
||||
<ak-tabs ?vertical="${true}">
|
||||
@ -91,7 +91,7 @@ export class UserSettingsPage extends AKElement {
|
||||
<ak-user-settings-flow-executor></ak-user-settings-flow-executor>
|
||||
</div>
|
||||
<div class="pf-l-stack__item">
|
||||
${pwStage
|
||||
${pwStage.length > 0
|
||||
? html`<ak-user-settings-password
|
||||
configureUrl=${ifDefined(pwStage[0].configureUrl)}
|
||||
></ak-user-settings-password>`
|
||||
|
@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "Fixed working hours are an outdated concept: 71% of HR leaders agree"
|
||||
slug: 2023-05-12-fixed-working-hours-are-outdated
|
||||
authors:
|
||||
- name: Jens Langhammer
|
||||
title: CTO at Authentik Security Inc
|
||||
url: https://github.com/BeryJu
|
||||
image_url: https://github.com/BeryJu.png
|
||||
tags:
|
||||
- blog
|
||||
- flextime
|
||||
- working hours
|
||||
- employees
|
||||
- employers
|
||||
- flexible hours
|
||||
- job perks
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
Face it, it is difficult to write about high tech, IT-based, computer-centric jobs without feeling that a bit of privilege exists in this space. Many of us in the software industry have employers who are sympathetic to, or even promote, the concept of “flex-time” and other enticing perks.
|
||||
|
||||
It is a major perk, even a luxury, to not have to clock in at a specific hour and then somehow miraculously wrap up your work and clock out in exactly eight hours. An act as simple as stopping at a pastry shop before work, or taking an extra long morning walk, without fretting about the exact minutes on your watch, is a privilege… but one that IT workers are increasingly insisted on having.
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
> \***\*71% of HR leaders believe the Monday-Friday, 9-to-5 workweek is outdated, according to a 2022 [survey](https://www.capterra.com/resources/flexible-work-time/).**
|
||||
|
||||
It’s true that software companies in some countries are less amenable to flexible schedules and other relatively recents practices such as remote work or job-sharing, but the fact is that flexible working hours are still happening, a lot, even at the hard-core, old-school, corporate-style companies. And there’s a reason for this; being human.
|
||||
|
||||
### “I’ve got this!”
|
||||
|
||||
Humans prefer, inherently, to rely on our own instincts and analyses. When we feel empowered and trusted to work in the way that we feel is the most pragmatic, we tend to embrace the tasks in front of us with more enthusiasm and confidence (resulting in higher productivity). The opposite sensation, one of micro-management and lack of trust, freezes us in our tracks… and reduces productivity. Understandably, being dictated to about exactly _when_ one must do ones' various tasks implies a lack of trust.
|
||||
|
||||
> _Indeed, HR organizations are realizing that [strict work hours are a deterrent](https://www.capterra.com/resources/flexible-work-time/), and that the vast majority of employees will reject jobs that require a very specific start and end time._
|
||||
|
||||
Finishing a big project is rewarding, and when that goal is achieved, we are rewarded with a sense of accomplishment and self-approval (and hopefully recognition from your team and leadership). That feeling of success is what keeps us motivated; we value outcomes, the tangible deliverables, but we do not derive enjoyment from the actual time it took to complete the task. That is, we don’t celebrate the hours and weeks of work, but rather the outcome.
|
||||
|
||||
We know that employees are happier and feel more valued when their managers measure performance based on outcomes, instead of the amount of time spent on a project or task, so it makes sense that so many companies are promoting a policy flexible working hours.
|
||||
|
||||
### Efficiency of cognitive optimization
|
||||
|
||||
Software developers, and many others in this field, rely on brain-power, brain-fitness, brain-agility, and frankly, on the willingness of our brains to cooperate with the task at hand. In reality, we are mostly at the mercy of our brains, and what they feel up to working on at any given moment.
|
||||
|
||||
> “_[Cognition is dynamic.](https://pubmed.ncbi.nlm.nih.gov/30266263/)_”
|
||||
|
||||
However, that dynamism can be harnessed and used to optimize our cognitive work. Being aware of what state our brains are in at the moment allows us to select tasks that are appropriate for the current cognitive “mood”. Feeling super-alert and deeply technical? Go ahead and dive deep to pump out a chunk of code for a new feature, or script a test plan, or refactor to solve a longstanding bug. Or, if you are feeling mentally exhausted but have excess energy, use that energy to do rote tasks that don’t require much brain work. Or, as is sometimes the case with work that demands highly functioning cognitive effort, perhaps you are simply burnt out and unable to focus at all. Take a long walk, play a quick game, step away from your work and brew a second cup of coffee… log in late, log off early, and get back to it when your brain is ready.
|
||||
|
||||
While this might seem to be verging on irresponsible, using a flexible work schedule to your advantage can be a huge benefit, for both employee and employer. By playing into, and working collaboratively, with our own brains we can actually increase productivity, creativity, and innovation.
|
||||
|
||||
This skill of optimizing for when you work on what type of tasks can be considered as the antidote to the downsides and churn of intense multi-tasking. Recent studies have shown that doing too much multitasking at work can be counter-productive, because of the high “[switching costs](https://www.apa.org/topics/research/multitasking)”. If, instead of forcing our brains to frequently switch contexts and start the next task on the list, we first assess the current cognitive “mood” of our brains and then work on the types of tasks that align well with that mood, we can increase our productivity (and happiness).
|
||||
|
||||
### Reality of life
|
||||
|
||||
It’s a welcome cliche nowadays to acknowledge that everyone has, at some point or another, “something stressful going on in their life”. This awareness of the reality of life challenges is yet another reason why flexible work schedules are considered humane perks, and why employers are wise to pragmatically acknowledge this and adjust their expectations.
|
||||
|
||||
> _“Peak productivity doesn’t always align with traditional business hours.” ([source](https://www.capterra.com/resources/flexible-work-time/))_
|
||||
|
||||
Life isn’t neat. There are school obligations, family needs, personal care, doctor’s appointments, and the list goes on. The reality of office hours, and daylight hours, is inflexible. Work hours, however can be flexible.
|
||||
|
||||
### Global team distribution
|
||||
|
||||
Here at [Authentik Security](https://goauthentik.io/), we are globally distributed with three different time zones in the US and two in Europe. Many companies, including large international companies, have worked with even more extreme time zone spread, for decades, so this model is proven.
|
||||
|
||||
This model of wide-spread working hours across teams is yet another pragmatic reason for implementing flexible working hours. Allowing European-based team members flexibility in choosing to start their work-day later in order to collaborate with US-based colleagues means that the European employees can have calm mornings focused on family or personal needs, while the US-based employees can start earlier and log off mid-afternoon. Or another alternative is implementing “split hours” where an employee works some hours in the morning, and some later in the day, with a longer break in the middle.
|
||||
|
||||
Ultimately, the ability of the employee to choose how best to get their work done, and when to work on what tasks, is both a luxurious perk and a pragmatic necessity, at least in the somewhat privileged world of software.
|
@ -2,7 +2,17 @@
|
||||
|
||||
Blueprints are YAML files, which can use some additional tags to ease blueprint creation.
|
||||
|
||||
## Structure
|
||||
## Schema
|
||||
|
||||
The blueprint schema is available under `https://goauthentik.io/blueprints/schema.json`. It is also possible to target a specific version's blueprint schema by using `https://version-2023-4.goauthentik.io/blueprints/schema.json`.
|
||||
|
||||
To use the schema with Visual Studio code and the YAML extension, add this comment at the top of your blueprint files:
|
||||
|
||||
```yaml
|
||||
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||
|
@ -6,12 +6,12 @@ If you want to only make changes on the UI, you don't need a backend running fro
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node (any recent version should work, we use 20.x to build)
|
||||
- Node.js (any recent version should work; we use 20.x to build)
|
||||
- Make (again, any recent version should work)
|
||||
- Docker and docker-compose
|
||||
- Docker and Docker Compose
|
||||
|
||||
:::info
|
||||
Depending on platform, some native dependencies might be required. On macOS, run `brew install node@20`, and for docker `brew install --cask docker`
|
||||
Depending on platform, some native dependencies might be required. On macOS, run `brew install node@20`, and for Docker `brew install --cask docker`
|
||||
:::
|
||||
|
||||
### Instructions
|
||||
|
@ -5,17 +5,21 @@ title: Full development environment
|
||||
## Requirements
|
||||
|
||||
- Python 3.11
|
||||
- poetry, which is used to manage dependencies, and can be installed with `pip install poetry`
|
||||
- Poetry, which is used to manage dependencies
|
||||
- Go 1.20
|
||||
- Node 20
|
||||
- Node.js 20
|
||||
- PostgreSQL (any recent version will do)
|
||||
- Redis (any recent version will do)
|
||||
|
||||
## Services Setup
|
||||
|
||||
For PostgreSQL and Redis, you can use the docker-compose file in `scripts/`.
|
||||
For PostgreSQL and Redis, you can use the `docker-compose.yml` file in `/scripts`.To use these pre-configured database instances, navigate to the `/scripts` directory in your local copy of the authentik git repo, and run `docker compose up -d`.
|
||||
You can also use a native install, if you prefer.
|
||||
|
||||
:::info
|
||||
If you use locally installed databases, the PostgreSQL credentials given to authentik should have permissions for `CREATE DATABASE` and `DROP DATABASE`, because authentik creates a temporary database for tests.
|
||||
:::
|
||||
|
||||
## Backend Setup
|
||||
|
||||
:::info
|
||||
@ -23,12 +27,14 @@ Depending on your platform, some native dependencies might be required. On macOS
|
||||
:::
|
||||
|
||||
:::info
|
||||
As long as [this issue](https://github.com/xmlsec/python-xmlsec/issues/252) is open, a workaround is required to install a compatible version of `libxmlsec1` with brew, see [this comment](https://github.com/xmlsec/python-xmlsec/issues/254#issuecomment-1511135314).
|
||||
As long as [this issue](https://github.com/xmlsec/python-xmlsec/issues/252) about `libxmlsec-1.3.0` is open, a workaround is required to install a compatible version of `libxmlsec1` with brew, see [this comment](https://github.com/xmlsec/python-xmlsec/issues/254#issuecomment-1511135314).
|
||||
:::
|
||||
|
||||
First, you need to create an isolated Python environment. To create the environment and install dependencies, run the following commands in the same directory as your authentik git repository:
|
||||
|
||||
```shell
|
||||
poetry shell # Creates a python virtualenv, and activates it in a new shell
|
||||
poetry install # Install all required dependencies, including development dependencies
|
||||
make install # Install all required dependencies for Python and Javascript, including development dependencies
|
||||
```
|
||||
|
||||
To configure authentik to use the local databases, we need a local config file. This file can be generated by running `make gen-dev-config`.
|
||||
@ -54,6 +60,11 @@ This will immediately update the UI with any changes you make so you can see the
|
||||
|
||||
To format the frontend code, run `make web`.
|
||||
|
||||
## Running
|
||||
## Running authentik
|
||||
|
||||
Now that the backend and frontend have been setup and built, you can start authentik by running `ak server`. authentik should now be accessible at `http://localhost:9000`.
|
||||
|
||||
:::info
|
||||
To define a password for the default admin (called **akadmin**), you can manually enter the `/if/flow/initial-setup/` path in the browser address bar to launch the initial flow.
|
||||
Example: http://localhost:9000/if/flow/initial-setup/
|
||||
:::
|
||||
|
@ -6,7 +6,7 @@ If you want to only make changes to the website, you only need node.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node (any recent version should work, we use 20.x to build)
|
||||
- Node.js (any recent version should work; we use 20.x to build)
|
||||
- Make (again, any recent version should work)
|
||||
|
||||
:::info
|
||||
|
9
website/docs/installation/index.md
Normal file
9
website/docs/installation/index.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Installation
|
||||
---
|
||||
|
||||
Everything you need to get authentik up and running! For information about upgrading to a new version, refer to the <b>Upgrade</b> section in the relevant [Release Notes](../releases).
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
<DocCardList />
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,12 @@
|
||||
const fs = require("fs");
|
||||
const sidebar = require("./sidebars.js");
|
||||
|
||||
const releases = sidebar.docs
|
||||
.filter((doc) => doc.link?.slug === "releases")[0]
|
||||
.items.filter((release) => typeof release === "string");
|
||||
|
||||
const footerEmail = fs.readFileSync("src/footer.html", { encoding: "utf-8" });
|
||||
|
||||
/** @type {import('@docusaurus/types').DocusaurusConfig} */
|
||||
module.exports = {
|
||||
title: "authentik",
|
||||
@ -81,6 +84,14 @@ module.exports = {
|
||||
},
|
||||
footer: {
|
||||
links: [
|
||||
{
|
||||
title: "Subscribe to authentik News",
|
||||
items: [
|
||||
{
|
||||
html: footerEmail,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Documentation",
|
||||
items: [
|
||||
|
@ -10,6 +10,13 @@ title: Amazon Web Services
|
||||
Amazon Web Services (AWS) is the world’s most comprehensive and broadly adopted cloud platform, offering over 175 fully featured services from data centers globally. Millions of customers—including the fastest-growing startups, largest enterprises, and leading government agencies—are using AWS to lower costs, become more agile, and innovate faster.
|
||||
:::
|
||||
|
||||
## Select your method
|
||||
|
||||
There are two ways to perform the integration. The classic IAM SAML way, or the 'newer' IAM Identity Center way.
|
||||
This all depends on your preference and needs.
|
||||
|
||||
# Method 1: Classic IAM
|
||||
|
||||
## Preparation
|
||||
|
||||
The following placeholders will be used:
|
||||
@ -75,3 +82,94 @@ To use the user's username, use this snippet
|
||||
```python
|
||||
return user.username
|
||||
```
|
||||
|
||||
# Method 2: IAM Identity Center
|
||||
|
||||
## Preparation
|
||||
|
||||
The following placeholders are used:
|
||||
|
||||
- `authentik.company` is the FQDN of the authentik install.
|
||||
|
||||
Additional Preparation:
|
||||
|
||||
- A certificate to sign SAML assertions is required. You can use authentik's default certificate, or provide/generate one yourself.
|
||||
- You may pre-create an AWS application.
|
||||
|
||||
## How to integrate with AWS
|
||||
|
||||
In AWS:
|
||||
|
||||
- In AWS navigate to: `IAM Identity Center -> Settings -> Identity Source (tab)`
|
||||
- On the right side click `Actions -> Change identity source`
|
||||
- Select `External Identity Provider`
|
||||
- Under `Service Provider metadata` download the metadata file.
|
||||
|
||||
Now go to your authentik instance, and perform the following steps.
|
||||
|
||||
- Under _Providers_ create a new _SAML Provider from metadata_. Give it a name, and upload the metadata file AWS gave you.
|
||||
- Click _Next_. Give it a name, and close the file.
|
||||
- If you haven't done so yet, create an application for AWS and connect the provider to it.
|
||||
- Navigate to the provider you've just created, and then select _Edit_
|
||||
- Copy the _Issuer URL_ to the _Audience_ field.
|
||||
- Under _Advanced Protocol Settings_ set a _Signing Certificate_
|
||||
- Save and Close.
|
||||
- Under _Related Objects_ download the _Metadata file_, and the _Signing Certificate_
|
||||
|
||||
Now go back to your AWS instance
|
||||
|
||||
- Under `Identity provider metadata` upload both the the `Metadata` file and `Signing Certificate` that authentik gave you.
|
||||
- Click `Next`.
|
||||
- In your settings pane, under the tab `Identity Source`, click `Actions -> Manage Authentication`.
|
||||
- Take note of the `AWS access portal sign-in URL` (this is especially important if you changed it from the default).
|
||||
|
||||
Now go back to your authentik instance.
|
||||
|
||||
- Navigate to the Application that you created for AWS and click _Edit_.
|
||||
- Under _UI Settings_ make sure the _Start URL_ matches the _AWS access portal sign-in URL_
|
||||
|
||||
## Caveats and Troubleshooting
|
||||
|
||||
- Users need to already exist in AWS in order to use them through authentik. AWS will throw an error if it doesn't recognise the user.
|
||||
- In case you're stuck, you can see the SSO logs in Amazon CloudTrail -> Event History. Look for `ExtenalIdPDirectoryLogin`
|
||||
|
||||
Note:
|
||||
|
||||
## Optional: Automated provisioning with SCIM
|
||||
|
||||
Some people may opt TO USE the automatic provisioning feature called SCIM (System for Cross-domain Identity Management).
|
||||
SCIM allows you to synchronize (part of) your directory to AWS's IAM, saving you the hassle of having to create users by hand.
|
||||
In order to do so, take the following steps in your AWS Identity Center:
|
||||
|
||||
- In your `Settings` pane, locate the `Automatic Provisioning` Info box. Click `Enable`.
|
||||
- AWS will give you an `SCIM Endpoint` and a `Access Token`. Take note of these values.
|
||||
|
||||
Go back to your authentik instance
|
||||
|
||||
- Navigate to _Providers_ -> _Create_
|
||||
- Select _SCIM Provider_
|
||||
- Give it a name, under _URL_ enter the _SCIM Endpoint_, and then under _Token_ enter the _Access Token_ AWS provided you with.
|
||||
- Optionally, change the user filtering settings to your liking. Click _Finish_
|
||||
|
||||
- Go to _Customization -> Property Mappings_
|
||||
- Click _Create -> SCIM Mapping_
|
||||
- Make sure to give the mapping a name that's lexically lower than `authentik default`, for example `AWS SCIM User mapping`
|
||||
- As the expression, enter:
|
||||
|
||||
```python
|
||||
# This expression strips the default mapping from its 'photos' attribute,
|
||||
# which is a forbidden property in AWS IAM.
|
||||
return {
|
||||
"photos": None,
|
||||
}
|
||||
```
|
||||
|
||||
- Click _Save_. Navigate back to your SCIM provider, click _Edit_
|
||||
- Under _User Property Mappings_ select the default mapping and the mapping that you just created.
|
||||
- Click _Update_
|
||||
|
||||
- Navigate to your application, click _Edit_.
|
||||
- Under _Backchannel providers_ add the SCIM provider that you created.
|
||||
- Click _Update_
|
||||
|
||||
The SCIM provider should sync automatically whenever you create/alter/remove anything. You can manually sync by going to your SCIM provider and click the _Run sync again_ button. Once the SCIM provider has synced, you should see the users and groups in your AWS IAM center.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user