Compare commits

..

49 Commits

Author SHA1 Message Date
430a207865 release: 2023.1.1 2023-01-23 11:34:58 +01:00
894873b373 core: compile backend translations (#4489)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2023-01-23 11:00:35 +01:00
1ce2a1b846 stages/email: update tests
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-23 10:43:49 +01:00
4731ccfafe stages/email: fix a typo in email template (#4485)
fix a typo in main content

Signed-off-by: Loan J <joliveau.loan@gmail.com>

Signed-off-by: Loan J <joliveau.loan@gmail.com>
2023-01-23 10:22:49 +01:00
3e9c28d0a4 web: bump @babel/plugin-proposal-decorators from 7.20.7 to 7.20.13 in /web (#4486)
web: bump @babel/plugin-proposal-decorators in /web

Bumps [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) from 7.20.7 to 7.20.13.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.13/packages/babel-plugin-proposal-decorators)

---
updated-dependencies:
- dependency-name: "@babel/plugin-proposal-decorators"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:21:46 +01:00
12d4394d73 web: bump @rollup/plugin-commonjs from 24.0.0 to 24.0.1 in /web (#4487)
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 24.0.0 to 24.0.1.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/commonjs-v24.0.1/packages/commonjs)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-commonjs"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:21:24 +01:00
b872e7072d core: bump paramiko from 2.12.0 to 3.0.0 (#4488)
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.12.0 to 3.0.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.12.0...3.0.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:20:51 +01:00
b0ea657b18 ci: fix incorrect action for geoip secrets for release pipeline
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-22 19:19:41 +01:00
a5f26b2ce0 ci: use bot token to create release
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-22 19:09:49 +01:00
c1b9b5c5e2 stages/authenticator_totp: url quote TOTP issuer instead of slugifying (#4482)
* Fix TOTP issuer mangling

* Fix OTP issuer mangling

* sort imports

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

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-01-22 16:37:47 +00:00
b288393cd4 stages/invitation: handle incorrectly formatted token
closes #4481

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-22 00:03:39 +01:00
767ffc09d0 web/admin: fix plex source authorization flow not being shown correctly
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-21 14:55:13 +01:00
446dc0a17b website/docs: prepare 2023.1.1
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-20 14:25:20 +01:00
c85474ec37 root: update supported versions
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-20 14:23:21 +01:00
3a59b75f4a website/docs: update ldap provider docs
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-20 11:46:57 +01:00
8deac81364 outposts/ldap: fix queries filtering objectClass with non-lowercase values
closes #2756

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-20 11:42:23 +01:00
98485c528e ci: build beta for amd64 and arm64 (#4468)
* ci: build for arm64, but independently

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

* add notice to beta

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

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 21:41:56 +01:00
1a5b626f96 root: match warning exclusions in pytest
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 20:34:51 +01:00
5736a1542c stages/authenticator_sms: fix code not being sent when phone_number is in context
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 20:19:23 +01:00
43854dc828 outposts/proxy: fix panic due to IsSet misbehaving
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 18:22:55 +01:00
64af78110a ci: bump golangcilint timeout
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 18:17:18 +01:00
59be3c7746 website/docs: add docs for validating phone numbers before SMS enrollment
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 17:57:52 +01:00
9e30f01fce web/admin: don't enable execution logging by default
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 17:57:34 +01:00
fc8fe5317a stages: always use get_pending_user instead of getting context user
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 17:57:21 +01:00
92090ced9f web/elements: fix pf-c-switch not rendering correctly in pure tables
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 15:47:11 +01:00
ce47d4cf39 web/admin: link group of notification rule
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 15:46:37 +01:00
c11367553e providers/proxy: fix issuer for embedded outpost (#4480)
fix issuer for embedded outpost

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

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 15:39:30 +01:00
c61529e4d4 sources/ldap: add e2e LDAP source tests (#4462)
* start adding more LDAP source tests

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

* improve healthcheck

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

* try local webdriver

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

* add full samba tests

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

* fix locale types

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

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 15:03:56 +01:00
8709f3300c tests: fix OIDC tests running twice
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 12:28:51 +01:00
e78bc1b32f web/admin: improve display of system task exception
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 12:13:11 +01:00
89c4a7b4a4 web/admin: improve display of rule severity
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 12:09:53 +01:00
9701907b82 web: bump @lingui/macro from 3.15.0 to 3.16.0 in /web (#4473) 2023-01-19 10:44:50 +01:00
7ac73bfcf9 web: bump @lingui/cli from 3.15.0 to 3.16.0 in /web (#4478) 2023-01-19 10:44:25 +01:00
1423d5d45b web: bump @lingui/core from 3.15.0 to 3.16.0 in /web (#4474) 2023-01-19 10:19:42 +01:00
768ff67e8c web: bump core-js from 3.27.1 to 3.27.2 in /web (#4475) 2023-01-19 10:15:12 +01:00
b13deefd91 web: bump chart.js from 4.1.2 to 4.2.0 in /web (#4476) 2023-01-19 10:14:50 +01:00
69e445211e core: bump goauthentik.io/api/v3 from 3.2022122.8 to 3.2023010.1 (#4479) 2023-01-19 10:14:28 +01:00
ada8fc2a55 web: bump @lingui/detect-locale from 3.15.0 to 3.16.0 in /web (#4477) 2023-01-19 10:14:14 +01:00
d9cc45f9ce web/elements: fix SearchSelect not working on safari
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-19 00:08:23 +01:00
515a402db7 web/flows: fix flow executor background overlay in safari
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 20:43:19 +01:00
813f70b806 blueprints: fix OOB email field overwriting user settings email field
closes #4317

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 19:40:47 +01:00
a302a72379 crypto: fallback when no SAN values are given
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 19:40:24 +01:00
e390f5b2d1 providers/oauth2: more x5c and ecdsa x/y tests (#4463)
* add option to exclude x5*

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

#4082

* cleanup jwks, add flaky test

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

* add workaround based on https://github.com/jpadilla/pyjwt/issues/709

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

* don't rstrip hashes

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

* keycloak seems to strip equals

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

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 18:11:36 +00:00
f09305a444 root: don't specify bind IP in compose file
closes #4470

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 19:03:36 +01:00
60189ce9ca add tests to prevent empty SAN
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 18:59:10 +01:00
fdc445e6a1 ensure we don't generate an empty SAN certificate
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 18:44:41 +01:00
e3f8afcf80 web: bump API Client version (#4469)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
2023-01-18 16:27:20 +00:00
9e2e8132a6 Merge branch 'version-2023.1' 2023-01-18 17:14:10 +01:00
26f9bbeefa website/docs: add 2023.1 to sidebar
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-01-18 16:36:03 +01:00
79 changed files with 1095 additions and 424 deletions

View File

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

View File

@ -38,6 +38,14 @@ runs:
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
```
For arm64, use these values:
```shell
AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=${{ inputs.tag }}-arm64
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
```
Afterwards, run the upgrade commands from the latest release notes.
</details>
<details>
@ -54,6 +62,17 @@ runs:
tag: ${{ inputs.tag }}
```
For arm64, use these values:
```yaml
authentik:
outposts:
container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
image:
repository: ghcr.io/goauthentik/dev-server
tag: ${{ inputs.tag }}-arm64
```
Afterwards, run the upgrade commands from the latest release notes.
</details>
edit-mode: replace

View File

@ -17,6 +17,9 @@ outputs:
sha:
description: "sha"
value: ${{ steps.ev.outputs.sha }}
shortHash:
description: "shortHash"
value: ${{ steps.ev.outputs.shortHash }}
version:
description: "version"
value: ${{ steps.ev.outputs.version }}
@ -53,6 +56,7 @@ runs:
print("branchNameContainer=%s" % safe_branch_name, file=_output)
print("timestamp=%s" % int(time()), file=_output)
print("sha=%s" % os.environ["GITHUB_SHA"], file=_output)
print("shortHash=%s" % os.environ["GITHUB_SHA"][:7], file=_output)
print("shouldBuild=%s" % should_build, file=_output)
print("version=%s" % version, file=_output)
print("versionFamily=%s" % version_family, file=_output)

View File

@ -118,13 +118,13 @@ jobs:
- name: proxy
glob: tests/e2e/test_provider_proxy*
- name: oauth
glob: tests/e2e/test_provider_oauth2_!(oidc) tests/e2e/test_source_oauth*
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
- name: oauth-oidc
glob: tests/e2e/test_provider_oauth2_oidc*
glob: tests/e2e/test_provider_oidc*
- name: saml
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
- name: ldap
glob: tests/e2e/test_provider_ldap*
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
- name: flows
glob: tests/e2e/test_flows*
steps:
@ -148,7 +148,6 @@ jobs:
npm run build
- name: run e2e
run: |
shopt -s extglob
poetry run coverage run manage.py test ${{ matrix.job.glob }}
poetry run coverage xml
- if: ${{ always() }}
@ -170,11 +169,6 @@ jobs:
needs: ci-core-mark
runs-on: ubuntu-latest
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
arch:
- 'linux/amd64'
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
@ -202,14 +196,49 @@ jobs:
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
tags: |
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.sha }}
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}
build-args: |
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
platforms: ${{ matrix.arch }}
- name: Comment on PR
if: github.event_name == 'pull_request'
continue-on-error: true
uses: ./.github/actions/comment-pr-instructions
with:
tag: gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.sha }}
tag: gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}
build-arm64:
needs: ci-core-mark
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
- name: Login to Container Registry
uses: docker/login-action@v2
if: ${{ steps.ev.outputs.shouldBuild == 'true' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker Image
uses: docker/build-push-action@v3
with:
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
tags: |
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-arm64
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}-arm64
build-args: |
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
platforms: linux/arm64

View File

@ -28,6 +28,8 @@ jobs:
run: make gen-client-go
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
args: --timeout 5000s
test-unittest:
runs-on: ubuntu-latest
steps:
@ -86,7 +88,6 @@ jobs:
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
tags: |
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchNameContainer }}
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.sha }}
file: ${{ matrix.type }}.Dockerfile
build-args: |

View File

@ -31,7 +31,7 @@ jobs:
uses: docker/build-push-action@v3
with:
push: ${{ github.event_name == 'release' }}
secrets:
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
tags: |
@ -88,9 +88,6 @@ jobs:
ghcr.io/goauthentik/${{ matrix.type }}:latest
file: ${{ matrix.type }}.Dockerfile
platforms: linux/amd64,linux/arm64
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
build-args: |
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
build-outpost-binary:

View File

@ -26,14 +26,14 @@ jobs:
id: get_version
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.BOT_GITHUB_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.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ steps.get_version.outputs.result }}

View File

@ -19,6 +19,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.BOT_GITHUB_TOKEN }}
- name: Setup authentik env
uses: ./.github/actions/setup
- name: run compile
@ -27,7 +29,7 @@ jobs:
uses: peter-evans/create-pull-request@v4
id: cpr
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.BOT_GITHUB_TOKEN }}
branch: compile-backend-translation
commit-message: "core: compile backend translations"
title: "core: compile backend translations"

View File

@ -6,8 +6,8 @@ Authentik takes security very seriously. We follow the rules of [responsible dis
| Version | Supported |
| --------- | ------------------ |
| 2022.11.x | :white_check_mark: |
| 2022.12.x | :white_check_mark: |
| 2023.1.x | :white_check_mark: |
## Reporting a Vulnerability

View File

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

View File

@ -235,9 +235,11 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
data = CertificateGenerationSerializer(data=request.data)
if not data.is_valid():
return Response(data.errors, status=400)
raw_san = data.validated_data.get("subject_alt_name", "")
sans = raw_san.split(",") if raw_san != "" else []
builder = CertificateBuilder(data.validated_data["common_name"])
builder.build(
subject_alt_names=data.validated_data.get("subject_alt_name", "").split(","),
subject_alt_names=sans,
validity_days=int(data.validated_data["validity_days"]),
)
instance = builder.save()

View File

@ -57,7 +57,10 @@ class CertificateBuilder:
one_day = datetime.timedelta(1, 0, 0)
self.__private_key = self.generate_private_key()
self.__public_key = self.__private_key.public_key()
alt_names: list[x509.GeneralName] = [x509.DNSName(x) for x in subject_alt_names or []]
alt_names: list[x509.GeneralName] = []
for alt_name in subject_alt_names or []:
if alt_name.strip() != "":
alt_names.append(x509.DNSName(alt_name))
self.__builder = (
x509.CertificateBuilder()
.subject_name(
@ -76,12 +79,15 @@ class CertificateBuilder:
]
)
)
.add_extension(x509.SubjectAlternativeName(alt_names), critical=True)
.not_valid_before(datetime.datetime.today() - one_day)
.not_valid_after(datetime.datetime.today() + datetime.timedelta(days=validity_days))
.serial_number(int(uuid.uuid4()))
.public_key(self.__public_key)
)
if alt_names:
self.__builder = self.__builder.add_extension(
x509.SubjectAlternativeName(alt_names), critical=True
)
self.__certificate = self.__builder.sign(
private_key=self.__private_key,
algorithm=hashes.SHA256(),

View File

@ -4,6 +4,8 @@ from json import loads
from os import makedirs
from tempfile import TemporaryDirectory
from cryptography.x509.extensions import SubjectAlternativeName
from cryptography.x509.general_name import DNSName
from django.urls import reverse
from rest_framework.test import APITestCase
@ -70,11 +72,43 @@ class TestCrypto(APITestCase):
def test_builder_api(self):
"""Test Builder (via API)"""
self.client.force_login(create_test_admin_user())
name = generate_id()
self.client.post(
reverse("authentik_api:certificatekeypair-generate"),
data={"common_name": "foo", "subject_alt_name": "bar,baz", "validity_days": 3},
data={"common_name": name, "subject_alt_name": "bar,baz", "validity_days": 3},
)
self.assertTrue(CertificateKeyPair.objects.filter(name="foo").exists())
key = CertificateKeyPair.objects.filter(name=name).first()
self.assertIsNotNone(key)
ext: SubjectAlternativeName = key.certificate.extensions[0].value
self.assertIsInstance(ext, SubjectAlternativeName)
self.assertIsInstance(ext[0], DNSName)
self.assertEqual(ext[0].value, "bar")
self.assertIsInstance(ext[1], DNSName)
self.assertEqual(ext[1].value, "baz")
def test_builder_api_empty_san(self):
"""Test Builder (via API)"""
self.client.force_login(create_test_admin_user())
name = generate_id()
self.client.post(
reverse("authentik_api:certificatekeypair-generate"),
data={"common_name": name, "subject_alt_name": "", "validity_days": 3},
)
key = CertificateKeyPair.objects.filter(name=name).first()
self.assertIsNotNone(key)
self.assertEqual(len(key.certificate.extensions), 0)
def test_builder_api_empty_san_multiple(self):
"""Test Builder (via API)"""
self.client.force_login(create_test_admin_user())
name = generate_id()
self.client.post(
reverse("authentik_api:certificatekeypair-generate"),
data={"common_name": name, "subject_alt_name": ", ", "validity_days": 3},
)
key = CertificateKeyPair.objects.filter(name=name).first()
self.assertIsNotNone(key)
self.assertEqual(len(key.certificate.extensions), 0)
def test_builder_api_invalid(self):
"""Test Builder (via API) (invalid)"""

View File

@ -448,7 +448,7 @@ class NotificationTransport(SerializerModel):
# pyright: reportGeneralTypeIssues=false
return send_mail(mail.__dict__) # pylint: disable=no-value-for-parameter
except (SMTPException, ConnectionError, OSError) as exc:
raise NotificationTransportError from exc
raise NotificationTransportError(exc) from exc
@property
def serializer(self) -> "Serializer":

View File

@ -1,14 +1,42 @@
"""JWKS tests"""
import base64
import json
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import load_der_x509_certificate
from django.urls.base import reverse
from jwt import PyJWKSet
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_cert, create_test_flow
from authentik.crypto.models import CertificateKeyPair
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.models import OAuth2Provider
from authentik.providers.oauth2.tests.utils import OAuthTestCase
TEST_CORDS_CERT = """
-----BEGIN CERTIFICATE-----
MIIB6jCCAZCgAwIBAgIRAOsdE3N7zETzs+7shTXGj5wwCgYIKoZIzj0EAwIwHjEc
MBoGA1UEAwwTYXV0aGVudGlrIDIwMjIuMTIuMjAeFw0yMzAxMTYyMjU2MjVaFw0y
NDAxMTIyMjU2MjVaMHgxTDBKBgNVBAMMQ0NsbDR2TzFJSGxvdFFhTGwwMHpES2tM
WENYdzRPUFF2eEtZN1NrczAuc2VsZi1zaWduZWQuZ29hdXRoZW50aWsuaW8xEjAQ
BgNVBAoMCWF1dGhlbnRpazEUMBIGA1UECwwLU2VsZi1zaWduZWQwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAAQAwOGam7AKOi5LKmb9lK1rAzA2JTppqrFiIaUdjqmH
ZICJP00Wt0dfqOtEjgMEv1Hhu1DmKZn2ehvpxwPSzBr5o1UwUzBRBgNVHREBAf8E
RzBFgkNCNkw4YlI0UldJRU42NUZLamdUTzV1YmRvNUZWdkpNS2lxdjFZeTRULnNl
bGYtc2lnbmVkLmdvYXV0aGVudGlrLmlvMAoGCCqGSM49BAMCA0gAMEUCIC/JAfnl
uC30ihqepbiMCaTaPMbL8Ka2Lk92IYfMhf46AiEAz9Kmv6HF2D4MK54iwhz2WqvF
8vo+OiGdTQ1Qoj7fgYU=
-----END CERTIFICATE-----
"""
TEST_CORDS_KEY = """
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKy6mPLJc5v71InMMvYaxyXI3xXpwQTPLyAYWVFnZHVioAoGCCqGSM49
AwEHoUQDQgAEAMDhmpuwCjouSypm/ZStawMwNiU6aaqxYiGlHY6ph2SAiT9NFrdH
X6jrRI4DBL9R4btQ5imZ9nob6ccD0swa+Q==
-----END EC PRIVATE KEY-----
"""
class TestJWKS(OAuthTestCase):
"""Test JWKS view"""
@ -29,6 +57,8 @@ class TestJWKS(OAuthTestCase):
body = json.loads(response.content.decode())
self.assertEqual(len(body["keys"]), 1)
PyJWKSet.from_dict(body)
key = body["keys"][0]
load_der_x509_certificate(base64.b64decode(key["x5c"][0]), default_backend()).public_key()
def test_hs256(self):
"""Test JWKS request with HS256"""
@ -60,3 +90,25 @@ class TestJWKS(OAuthTestCase):
body = json.loads(response.content.decode())
self.assertEqual(len(body["keys"]), 1)
PyJWKSet.from_dict(body)
def test_ecdsa_coords_mismatched(self):
"""Test JWKS request with ES256"""
cert = CertificateKeyPair.objects.create(
name=generate_id(),
key_data=TEST_CORDS_KEY,
certificate_data=TEST_CORDS_CERT,
)
provider = OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=create_test_flow(),
redirect_uris="http://local.invalid",
signing_key=cert,
)
app = Application.objects.create(name="test", slug="test", provider=provider)
response = self.client.get(
reverse("authentik_providers_oauth2:jwks", kwargs={"application_slug": app.slug})
)
body = json.loads(response.content.decode())
self.assertEqual(len(body["keys"]), 1)
PyJWKSet.from_dict(body)

View File

@ -15,27 +15,49 @@ from cryptography.hazmat.primitives.serialization import Encoding
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from django.views import View
from jwt.utils import base64url_encode
from authentik.core.models import Application
from authentik.crypto.models import CertificateKeyPair
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
def b64_enc(number: int) -> str:
"""Convert number to base64-encoded octet-value"""
length = ((number).bit_length() + 7) // 8
number_bytes = number.to_bytes(length, "big")
final = urlsafe_b64encode(number_bytes).rstrip(b"=")
return final.decode("ascii")
# See https://notes.salrahman.com/generate-es256-es384-es512-private-keys/
# and _CURVE_TYPES in the same file as the below curve files
ec_crv_map = {
SECP256R1: "P-256",
SECP384R1: "P-384",
SECP521R1: "P-512",
SECP521R1: "P-521",
}
min_length_map = {
SECP256R1: 32,
SECP384R1: 48,
SECP521R1: 66,
}
# https://github.com/jpadilla/pyjwt/issues/709
def bytes_from_int(val: int, min_length: int = 0) -> bytes:
"""Custom bytes_from_int that accepts a minimum length"""
remaining = val
byte_length = 0
while remaining != 0:
remaining >>= 8
byte_length += 1
length = max([byte_length, min_length])
return val.to_bytes(length, "big", signed=False)
def to_base64url_uint(val: int, min_length: int = 0) -> bytes:
"""Custom to_base64url_uint that accepts a minimum length"""
if val < 0:
raise ValueError("Must be a positive integer")
int_bytes = bytes_from_int(val, min_length)
if len(int_bytes) == 0:
int_bytes = b"\x00"
return base64url_encode(int_bytes)
class JWKSView(View):
@ -51,24 +73,25 @@ class JWKSView(View):
public_key: RSAPublicKey = private_key.public_key()
public_numbers = public_key.public_numbers()
key_data = {
"kid": key.kid,
"kty": "RSA",
"alg": JWTAlgorithms.RS256,
"use": "sig",
"kid": key.kid,
"n": b64_enc(public_numbers.n),
"e": b64_enc(public_numbers.e),
"n": to_base64url_uint(public_numbers.n).decode(),
"e": to_base64url_uint(public_numbers.e).decode(),
}
elif isinstance(private_key, EllipticCurvePrivateKey):
public_key: EllipticCurvePublicKey = private_key.public_key()
public_numbers = public_key.public_numbers()
curve_type = type(public_key.curve)
key_data = {
"kid": key.kid,
"kty": "EC",
"alg": JWTAlgorithms.ES256,
"use": "sig",
"kid": key.kid,
"x": b64_enc(public_numbers.x),
"y": b64_enc(public_numbers.y),
"crv": ec_crv_map.get(type(public_key.curve), public_key.curve.name),
"x": to_base64url_uint(public_numbers.x, min_length_map[curve_type]).decode(),
"y": to_base64url_uint(public_numbers.y, min_length_map[curve_type]).decode(),
"crv": ec_crv_map.get(curve_type, public_key.curve.name),
}
else:
return key_data

View File

@ -38,7 +38,6 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
try:
defaults = self.build_group_properties(group_dn, **attributes)
defaults["parent"] = self._source.sync_parent_group
self._logger.debug("Creating group with attributes", **defaults)
if "name" not in defaults:
raise IntegrityError("Name was not set by propertymappings")
# Special check for `users` field, as this is an M2M relation, and cannot be sync'd
@ -51,6 +50,7 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
},
defaults,
)
self._logger.debug("Created group with attributes", **defaults)
except (IntegrityError, FieldError, TypeError, AttributeError) as exc:
Event.new(
EventAction.CONFIGURATION_ERROR,

View File

@ -33,11 +33,10 @@ class LDAPSyncTests(TestCase):
"""Test Cached auth"""
self.source.property_mappings.set(
LDAPPropertyMapping.objects.filter(
Q(name__startswith="authentik default LDAP Mapping")
| Q(name__startswith="authentik default Active Directory Mapping")
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
)
)
self.source.save()
connection = PropertyMock(return_value=mock_ad_connection(LDAP_PASSWORD))
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
user_sync = UserLDAPSynchronizer(self.source)

View File

@ -1,5 +1,5 @@
"""Duo stage"""
from django.http import HttpRequest, HttpResponse
from django.http import HttpResponse
from django.utils.timezone import now
from rest_framework.fields import CharField
@ -10,7 +10,6 @@ from authentik.flows.challenge import (
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import InvalidStageError
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
@ -68,13 +67,6 @@ class AuthenticatorDuoStageView(ChallengeStageView):
}
)
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
if not user:
self.logger.debug("No pending user, continuing")
return self.executor.stage_ok()
return super().get(request, *args, **kwargs)
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
# Duo Challenge has already been validated
stage: AuthenticatorDuoStage = self.executor.current_stage

View File

@ -76,13 +76,17 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
return self.send_generic(token, device)
raise ValueError(f"invalid provider {self.provider}")
def get_message(self, token: str) -> str:
"""Get SMS message"""
return _("Use this code to authenticate in authentik: %(token)s" % {"token": token})
def send_twilio(self, token: str, device: "SMSDevice"):
"""send sms via twilio provider"""
client = Client(self.account_sid, self.auth)
try:
message = client.messages.create(
to=device.phone_number, from_=self.from_number, body=token
to=device.phone_number, from_=self.from_number, body=self.get_message(token)
)
LOGGER.debug("Sent SMS", to=device, message=message.sid)
except TwilioRestException as exc:
@ -95,6 +99,7 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
"From": self.from_number,
"To": device.phone_number,
"Body": token,
"Message": self.get_message(token),
}
if self.mapping:

View File

@ -12,9 +12,9 @@ from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
ChallengeTypes,
ErrorDetailSerializer,
WithUserInfoChallenge,
)
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
from authentik.stages.authenticator_sms.models import (
AuthenticatorSMSStage,
@ -47,15 +47,9 @@ class AuthenticatorSMSChallengeResponse(ChallengeResponse):
def validate(self, attrs: dict) -> dict:
"""Check"""
stage: AuthenticatorSMSStage = self.device.stage
if "code" not in attrs:
self.device.phone_number = attrs["phone_number"]
hashed_number = hash_phone_number(self.device.phone_number)
query = Q(phone_number=hashed_number) | Q(phone_number=self.device.phone_number)
if SMSDevice.objects.filter(query, stage=self.stage.executor.current_stage.pk).exists():
raise ValidationError(_("Invalid phone number"))
# No code yet, but we have a phone number, so send a verification message
stage.send(self.device.token, self.device)
self.stage.validate_and_send(attrs["phone_number"])
return super().validate(attrs)
if not self.device.verify_token(str(attrs["code"])):
raise ValidationError(_("Code does not match"))
@ -68,6 +62,17 @@ class AuthenticatorSMSStageView(ChallengeStageView):
response_class = AuthenticatorSMSChallengeResponse
def validate_and_send(self, phone_number: str):
"""Validate phone number and send message"""
stage: AuthenticatorSMSStage = self.executor.current_stage
hashed_number = hash_phone_number(phone_number)
query = Q(phone_number=hashed_number) | Q(phone_number=phone_number)
if SMSDevice.objects.filter(query, stage=stage.pk).exists():
raise ValidationError(_("Invalid phone number"))
# No code yet, but we have a phone number, so send a verification message
device: SMSDevice = self.request.session[SESSION_KEY_SMS_DEVICE]
stage.send(device.token, device)
def _has_phone_number(self) -> Optional[str]:
context = self.executor.plan.context
if "phone" in context.get(PLAN_CONTEXT_PROMPT, {}):
@ -95,24 +100,23 @@ class AuthenticatorSMSStageView(ChallengeStageView):
return response
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
if not user:
self.logger.debug("No pending user, continuing")
return self.executor.stage_ok()
# Currently, this stage only supports one device per user. If the user already
# has a device, just skip to the next stage
if SMSDevice.objects.filter(user=user).exists():
return self.executor.stage_ok()
user = self.get_pending_user()
stage: AuthenticatorSMSStage = self.executor.current_stage
if SESSION_KEY_SMS_DEVICE not in self.request.session:
device = SMSDevice(user=user, confirmed=False, stage=stage, name="SMS Device")
device.generate_token(commit=False)
self.request.session[SESSION_KEY_SMS_DEVICE] = device
if phone_number := self._has_phone_number():
device.phone_number = phone_number
self.request.session[SESSION_KEY_SMS_DEVICE] = device
try:
self.validate_and_send(phone_number)
except ValidationError as exc:
response = AuthenticatorSMSChallengeResponse()
response._errors.setdefault("phone_number", [])
response._errors["phone_number"].append(ErrorDetailSerializer(exc.detail))
return self.challenge_invalid(response)
return super().get(request, *args, **kwargs)
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:

View File

@ -80,6 +80,39 @@ class AuthenticatorSMSStageTests(FlowTestCase):
phone_number_required=False,
)
def test_stage_context_data(self):
"""test stage context data"""
self.client.get(
reverse("authentik_flows:configure", kwargs={"stage_uuid": self.stage.stage_uuid}),
)
sms_send_mock = MagicMock()
with (
patch(
(
"authentik.stages.authenticator_sms.stage."
"AuthenticatorSMSStageView._has_phone_number"
),
MagicMock(
return_value="1234",
),
),
patch(
"authentik.stages.authenticator_sms.models.AuthenticatorSMSStage.send",
sms_send_mock,
),
):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
)
sms_send_mock.assert_called_once()
self.assertStageResponse(
response,
self.flow,
self.user,
component="ak-stage-authenticator-sms",
phone_number_required=False,
)
def test_stage_submit_full(self):
"""test stage (submit)"""
self.client.get(

View File

@ -1,7 +1,8 @@
"""TOTP Setup stage"""
from urllib.parse import quote
from django.http import HttpRequest, HttpResponse
from django.http.request import QueryDict
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework.fields import CharField, IntegerField
@ -56,7 +57,7 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
data={
"type": ChallengeTypes.NATIVE.value,
"config_url": device.config_url.replace(
OTP_TOTP_ISSUER, slugify(self.request.tenant.branding_title)
OTP_TOTP_ISSUER, quote(self.request.tenant.branding_title)
),
}
)

View File

@ -376,7 +376,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
def challenge_valid(self, response: AuthenticatorValidationChallengeResponse) -> HttpResponse:
# All validation is done by the serializer
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
user = self.get_pending_user()
if not user:
if "webauthn" not in response.data:
return self.executor.stage_invalid()

View File

@ -26,7 +26,6 @@ from authentik.flows.challenge import (
ChallengeTypes,
WithUserInfoChallenge,
)
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
from authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id
@ -113,13 +112,6 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
}
)
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
if not user:
self.logger.debug("No pending user, continuing")
return self.executor.stage_ok()
return super().get(request, *args, **kwargs)
def get_response_instance(self, data: QueryDict) -> AuthenticatorWebAuthnChallengeResponse:
response: AuthenticatorWebAuthnChallengeResponse = super().get_response_instance(data)
response.request = self.request

View File

@ -17,7 +17,7 @@
<tr>
<td class="content-block">
{% blocktrans %}
You recently requested to change your password for you authentik account. Use the button below to set a new password.
You recently requested to change your password for your authentik account. Use the button below to set a new password.
{% endblocktrans %}
</td>
</tr>

View File

@ -62,9 +62,7 @@ class TestEmailStage(FlowTestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "authentik")
self.assertNotIn(
"You recently requested to change your password", mail.outbox[0].alternatives[0][0]
)
self.assertNotIn("Password Reset", mail.outbox[0].alternatives[0][0])
def test_without_user(self):
"""Test without pending user"""

View File

@ -2,6 +2,7 @@
from typing import Optional
from deepmerge import always_merger
from django.core.exceptions import ValidationError
from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext_lazy as _
@ -41,7 +42,11 @@ class InvitationStageView(StageView):
token = self.get_token()
if not token:
return None
invite: Invitation = Invitation.objects.filter(pk=token).first()
try:
invite: Invitation = Invitation.objects.filter(pk=token).first()
except ValidationError:
self.logger.debug("invalid invitation", token=token)
return None
if not invite:
self.logger.debug("invalid invitation", token=token)
return None

View File

@ -33,7 +33,7 @@ entries:
type: email
id: prompt-field-email
identifiers:
field_key: email
field_key: admin_email
label: Email
model: authentik_stages_prompt.prompt
- attrs:
@ -66,6 +66,8 @@ entries:
# by injecting "pending_user"
akadmin = ak_user_by(username="akadmin")
context["flow_plan"].context["pending_user"] = akadmin
# Remap the email value
context["prompt_data"]["email"] = context["prompt_data"]["admin_email"]
return True
id: policy-default-oobe-prefill-user
identifiers:

View File

@ -32,7 +32,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.0}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.1}
restart: unless-stopped
command: server
environment:
@ -47,10 +47,10 @@ services:
env_file:
- .env
ports:
- "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443"
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.0}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.1}
restart: unless-stopped
command: worker
environment:

2
go.mod
View File

@ -25,7 +25,7 @@ require (
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.1
goauthentik.io/api/v3 v3.2022122.8
goauthentik.io/api/v3 v3.2023010.1
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b

4
go.sum
View File

@ -382,8 +382,8 @@ go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZp
go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
goauthentik.io/api/v3 v3.2022122.8 h1:6yJ7w1K7/h79IJC9VDUV0pb12oSQnIOcghzCCPz3sEU=
goauthentik.io/api/v3 v3.2022122.8/go.mod h1:QM9J32HgYE4gL71lWAfAoXSPdSmLVLW08itfLI3Mo10=
goauthentik.io/api/v3 v3.2023010.1 h1:DQuf201pD+OKVnzpLKCaKw8IS397ewzMzFIGXyhmQ3w=
goauthentik.io/api/v3 v3.2023010.1/go.mod h1:QM9J32HgYE4gL71lWAfAoXSPdSmLVLW08itfLI3Mo10=
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=

View File

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

View File

@ -95,7 +95,12 @@ func IncludeObjectClass(searchOC string, ocs map[string]bool) bool {
return true
}
return ocs[searchOC]
for key, value := range ocs {
if strings.EqualFold(key, searchOC) {
return value
}
}
return false
}
func GetContainerEntry(filterOC string, dn string, ou string) *ldap.Entry {

View File

@ -70,19 +70,28 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
ks = oidc.NewRemoteKeySet(ctx, p.OidcConfiguration.JwksUri)
}
var verifier = oidc.NewVerifier(p.OidcConfiguration.Issuer, ks, &oidc.Config{
ClientID: *p.ClientId,
SupportedSigningAlgs: []string{"RS256", "HS256"},
})
redirectUri, _ := url.Parse(p.ExternalHost)
redirectUri.Path = path.Join(redirectUri.Path, "/outpost.goauthentik.io/callback")
redirectUri.RawQuery = url.Values{
CallbackSignature: []string{"true"},
}.Encode()
managed := false
if m := ak.Outpost.Managed.Get(); m != nil {
managed = *m == "goauthentik.io/outposts/embedded"
}
// Configure an OpenID Connect aware OAuth2 client.
endpoint := GetOIDCEndpoint(p, ak.Outpost.Config["authentik_host"].(string))
endpoint := GetOIDCEndpoint(
p,
ak.Outpost.Config["authentik_host"].(string),
managed,
)
verifier := oidc.NewVerifier(endpoint.Issuer, ks, &oidc.Config{
ClientID: *p.ClientId,
SupportedSigningAlgs: []string{"RS256", "HS256"},
})
oauth2Config := oauth2.Config{
ClientID: *p.ClientId,
ClientSecret: *p.ClientSecret,

View File

@ -15,11 +15,23 @@ type OIDCEndpoint struct {
TokenIntrospection string
EndSessionEndpoint string
JwksUri string
Issuer string
}
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoint {
func updateURL(rawUrl string, scheme string, host string) string {
u, err := url.Parse(rawUrl)
if err != nil {
return rawUrl
}
u.Host = host
u.Scheme = scheme
return u.String()
}
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string, embedded bool) OIDCEndpoint {
authUrl := p.OidcConfiguration.AuthorizationEndpoint
endUrl := p.OidcConfiguration.EndSessionEndpoint
tokenUrl := p.OidcConfiguration.TokenEndpoint
jwksUrl := p.OidcConfiguration.JwksUri
if browserHost, found := os.LookupEnv("AUTHENTIK_HOST_BROWSER"); found && browserHost != "" {
host := os.Getenv("AUTHENTIK_HOST")
@ -30,26 +42,15 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
ep := OIDCEndpoint{
Endpoint: oauth2.Endpoint{
AuthURL: authUrl,
TokenURL: p.OidcConfiguration.TokenEndpoint,
TokenURL: tokenUrl,
AuthStyle: oauth2.AuthStyleInParams,
},
EndSessionEndpoint: endUrl,
JwksUri: jwksUrl,
TokenIntrospection: p.OidcConfiguration.IntrospectionEndpoint,
Issuer: p.OidcConfiguration.Issuer,
}
authU, err := url.Parse(authUrl)
if err != nil {
return ep
}
endU, err := url.Parse(endUrl)
if err != nil {
return ep
}
jwksU, err := url.Parse(jwksUrl)
if err != nil {
return ep
}
if authU.Host != "localhost:8000" {
if !embedded {
return ep
}
if authentikHost == "" {
@ -60,14 +61,10 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
if err != nil {
return ep
}
authU.Host = aku.Host
authU.Scheme = aku.Scheme
endU.Host = aku.Host
endU.Scheme = aku.Scheme
jwksU.Host = aku.Host
jwksU.Scheme = aku.Scheme
ep.AuthURL = authU.String()
ep.EndSessionEndpoint = endU.String()
ep.JwksUri = jwksU.String()
ep.AuthURL = updateURL(authUrl, aku.Scheme, aku.Host)
ep.EndSessionEndpoint = updateURL(endUrl, aku.Scheme, aku.Host)
ep.JwksUri = updateURL(jwksUrl, aku.Scheme, aku.Host)
ep.TokenURL = updateURL(tokenUrl, aku.Scheme, aku.Host)
ep.Issuer = updateURL(ep.Issuer, aku.Scheme, aku.Host)
return ep
}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-13 14:37+0000\n"
"POT-Creation-Date: 2023-01-23 09:41+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"
@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: authentik/admin/api/tasks.py:126
#: authentik/admin/api/tasks.py:124
#, python-format
msgid "Successfully re-scheduled Task %(name)s!"
msgstr ""
@ -177,26 +177,26 @@ msgstr ""
msgid "Authenticated Sessions"
msgstr ""
#: authentik/core/sources/flow_manager.py:198
#: authentik/core/sources/flow_manager.py:197
msgid "source"
msgstr ""
#: authentik/core/sources/flow_manager.py:250
#: authentik/core/sources/flow_manager.py:248
msgid "Configured flow does not exist."
msgstr ""
#: authentik/core/sources/flow_manager.py:281
#: authentik/core/sources/flow_manager.py:333
#: authentik/core/sources/flow_manager.py:278
#: authentik/core/sources/flow_manager.py:330
#, python-format
msgid "Successfully authenticated with %(source)s!"
msgstr ""
#: authentik/core/sources/flow_manager.py:305
#: authentik/core/sources/flow_manager.py:302
#, python-format
msgid "Successfully linked %(source)s!"
msgstr ""
#: authentik/core/sources/flow_manager.py:324
#: authentik/core/sources/flow_manager.py:321
msgid "Source is not configured for enrollment."
msgstr ""
@ -255,9 +255,9 @@ msgid "Powered by authentik"
msgstr ""
#: authentik/core/views/apps.py:48
#: authentik/providers/oauth2/views/authorize.py:358
#: authentik/providers/oauth2/views/authorize.py:357
#: authentik/providers/oauth2/views/device_init.py:68
#: authentik/providers/saml/views/sso.py:69
#: authentik/providers/saml/views/sso.py:68
#, python-format
msgid "You're about to sign into %(application)s."
msgstr ""
@ -284,89 +284,89 @@ msgstr ""
msgid "Certificate-Key Pairs"
msgstr ""
#: authentik/events/models.py:288
#: authentik/events/models.py:287
msgid "Event"
msgstr ""
#: authentik/events/models.py:289
#: authentik/events/models.py:288
msgid "Events"
msgstr ""
#: authentik/events/models.py:295
#: authentik/events/models.py:294
msgid "authentik inbuilt notifications"
msgstr ""
#: authentik/events/models.py:296
#: authentik/events/models.py:295
msgid "Generic Webhook"
msgstr ""
#: authentik/events/models.py:297
#: authentik/events/models.py:296
msgid "Slack Webhook (Slack/Discord)"
msgstr ""
#: authentik/events/models.py:298
#: authentik/events/models.py:297
msgid "Email"
msgstr ""
#: authentik/events/models.py:316
#: authentik/events/models.py:315
msgid ""
"Only send notification once, for example when sending a webhook into a chat "
"channel."
msgstr ""
#: authentik/events/models.py:376
#: authentik/events/models.py:375
msgid "Severity"
msgstr ""
#: authentik/events/models.py:381
#: authentik/events/models.py:380
msgid "Dispatched for user"
msgstr ""
#: authentik/events/models.py:465
#: authentik/events/models.py:464
msgid "Notification Transport"
msgstr ""
#: authentik/events/models.py:466
#: authentik/events/models.py:465
msgid "Notification Transports"
msgstr ""
#: authentik/events/models.py:472
#: authentik/events/models.py:471
msgid "Notice"
msgstr ""
#: authentik/events/models.py:473
#: authentik/events/models.py:472
msgid "Warning"
msgstr ""
#: authentik/events/models.py:474
#: authentik/events/models.py:473
msgid "Alert"
msgstr ""
#: authentik/events/models.py:500
#: authentik/events/models.py:499
msgid "Notification"
msgstr ""
#: authentik/events/models.py:501
#: authentik/events/models.py:500
msgid "Notifications"
msgstr ""
#: authentik/events/models.py:521
#: authentik/events/models.py:520
msgid "Controls which severity level the created notifications will have."
msgstr ""
#: authentik/events/models.py:547
#: authentik/events/models.py:546
msgid "Notification Rule"
msgstr ""
#: authentik/events/models.py:548
#: authentik/events/models.py:547
msgid "Notification Rules"
msgstr ""
#: authentik/events/models.py:569
#: authentik/events/models.py:568
msgid "Webhook Mapping"
msgstr ""
#: authentik/events/models.py:570
#: authentik/events/models.py:569
msgid "Webhook Mappings"
msgstr ""
@ -374,7 +374,7 @@ msgstr ""
msgid "Task has not been run yet."
msgstr ""
#: authentik/flows/api/flows.py:297
#: authentik/flows/api/flows.py:292
#, python-format
msgid "Flow not applicable to current user/request: %(messages)s"
msgstr ""
@ -490,12 +490,12 @@ msgstr ""
msgid "%(value)s is not in the correct format of 'hours=3;minutes=1'."
msgstr ""
#: authentik/outposts/api/service_connections.py:132
#: authentik/outposts/api/service_connections.py:131
msgid ""
"You can only use an empty kubeconfig when connecting to a local cluster."
msgstr ""
#: authentik/outposts/api/service_connections.py:140
#: authentik/outposts/api/service_connections.py:139
msgid "Invalid kubeconfig"
msgstr ""
@ -925,7 +925,7 @@ msgstr ""
msgid "Device Tokens"
msgstr ""
#: authentik/providers/oauth2/views/authorize.py:412
#: authentik/providers/oauth2/views/authorize.py:411
#: authentik/providers/saml/views/flows.py:88
#, python-format
msgid "Redirecting to %(app)s..."
@ -974,36 +974,42 @@ msgid ""
"with internal_host."
msgstr ""
#: authentik/providers/proxy/models.py:79
#: authentik/providers/proxy/models.py:80
msgid ""
"When enabled, this provider will intercept the authorization header and "
"authenticate requests based on its value."
msgstr ""
#: authentik/providers/proxy/models.py:86
msgid "Set HTTP-Basic Authentication"
msgstr ""
#: authentik/providers/proxy/models.py:81
#: authentik/providers/proxy/models.py:88
msgid ""
"Set a custom HTTP-Basic Authentication header based on values from authentik."
msgstr ""
#: authentik/providers/proxy/models.py:86
#: authentik/providers/proxy/models.py:93
msgid "HTTP-Basic Username Key"
msgstr ""
#: authentik/providers/proxy/models.py:96
#: authentik/providers/proxy/models.py:103
msgid "HTTP-Basic Password Key"
msgstr ""
#: authentik/providers/proxy/models.py:152
#: authentik/providers/proxy/models.py:159
msgid "Proxy Provider"
msgstr ""
#: authentik/providers/proxy/models.py:153
#: authentik/providers/proxy/models.py:160
msgid "Proxy Providers"
msgstr ""
#: authentik/providers/saml/api/providers.py:261
#: authentik/providers/saml/api/providers.py:260
msgid "Invalid XML Syntax"
msgstr ""
#: authentik/providers/saml/api/providers.py:271
#: authentik/providers/saml/api/providers.py:270
#, python-format
msgid "Failed to import Metadata: %(message)s"
msgstr ""
@ -1174,7 +1180,7 @@ msgstr ""
msgid "LDAP Property Mappings"
msgstr ""
#: authentik/sources/ldap/signals.py:58
#: authentik/sources/ldap/signals.py:56
msgid "Password does not match Active Directory Complexity."
msgstr ""
@ -1323,7 +1329,7 @@ msgstr ""
msgid "User OAuth Source Connections"
msgstr ""
#: authentik/sources/oauth/views/callback.py:103
#: authentik/sources/oauth/views/callback.py:100
#, python-format
msgid "Authentication failed: %(reason)s"
msgstr ""
@ -1460,30 +1466,35 @@ msgstr ""
msgid "Optionally modify the payload being sent to custom providers."
msgstr ""
#: authentik/stages/authenticator_sms/models.py:176
#: authentik/stages/authenticator_sms/models.py:81
#, python-format
msgid "Use this code to authenticate in authentik: %(token)s"
msgstr ""
#: authentik/stages/authenticator_sms/models.py:181
msgid "SMS Authenticator Setup Stage"
msgstr ""
#: authentik/stages/authenticator_sms/models.py:177
#: authentik/stages/authenticator_sms/models.py:182
msgid "SMS Authenticator Setup Stages"
msgstr ""
#: authentik/stages/authenticator_sms/models.py:222
#: authentik/stages/authenticator_sms/models.py:227
msgid "SMS Device"
msgstr ""
#: authentik/stages/authenticator_sms/models.py:223
#: authentik/stages/authenticator_sms/models.py:228
msgid "SMS Devices"
msgstr ""
#: authentik/stages/authenticator_sms/stage.py:56
msgid "Invalid phone number"
#: authentik/stages/authenticator_sms/stage.py:55
#: authentik/stages/authenticator_totp/stage.py:42
#: authentik/stages/authenticator_totp/stage.py:45
msgid "Code does not match"
msgstr ""
#: authentik/stages/authenticator_sms/stage.py:61
#: authentik/stages/authenticator_totp/stage.py:41
#: authentik/stages/authenticator_totp/stage.py:44
msgid "Code does not match"
#: authentik/stages/authenticator_sms/stage.py:71
msgid "Invalid phone number"
msgstr ""
#: authentik/stages/authenticator_static/models.py:47
@ -1694,7 +1705,7 @@ msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:19
msgid ""
"\n"
" You recently requested to change your password for you "
" You recently requested to change your password for your "
"authentik account. Use the button below to set a new password.\n"
" "
msgstr ""
@ -1794,7 +1805,7 @@ msgstr ""
msgid "Invitations"
msgstr ""
#: authentik/stages/invitation/stage.py:61
#: authentik/stages/invitation/stage.py:66
msgid "Invalid invite/invite not found"
msgstr ""

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

20
poetry.lock generated
View File

@ -2084,27 +2084,25 @@ files = [
[[package]]
name = "paramiko"
version = "2.12.0"
version = "3.0.0"
description = "SSH2 protocol library"
category = "main"
optional = false
python-versions = "*"
python-versions = ">=3.6"
files = [
{file = "paramiko-2.12.0-py2.py3-none-any.whl", hash = "sha256:b2df1a6325f6996ef55a8789d0462f5b502ea83b3c990cbb5bbe57345c6812c4"},
{file = "paramiko-2.12.0.tar.gz", hash = "sha256:376885c05c5d6aa6e1f4608aac2a6b5b0548b1add40274477324605903d9cd49"},
{file = "paramiko-3.0.0-py3-none-any.whl", hash = "sha256:6bef55b882c9d130f8015b9a26f4bd93f710e90fe7478b9dcc810304e79b3cd8"},
{file = "paramiko-3.0.0.tar.gz", hash = "sha256:fedc9b1dd43bc1d45f67f1ceca10bc336605427a46dcdf8dec6bfea3edf57965"},
]
[package.dependencies]
bcrypt = ">=3.1.3"
cryptography = ">=2.5"
pynacl = ">=1.0.1"
six = "*"
bcrypt = ">=3.2"
cryptography = ">=3.3"
pynacl = ">=1.5"
[package.extras]
all = ["bcrypt (>=3.1.3)", "gssapi (>=1.4.1)", "invoke (>=1.3)", "pyasn1 (>=0.1.7)", "pynacl (>=1.0.1)", "pywin32 (>=2.1.8)"]
ed25519 = ["bcrypt (>=3.1.3)", "pynacl (>=1.0.1)"]
all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
invoke = ["invoke (>=1.3)"]
invoke = ["invoke (>=2.0)"]
[[package]]
name = "pathspec"

View File

@ -107,10 +107,14 @@ DJANGO_SETTINGS_MODULE = "authentik.root.settings"
python_files = ["tests.py", "test_*.py", "*_tests.py"]
junit_family = "xunit2"
addopts = "-p no:celery --junitxml=unittest.xml"
filterwarnings = [
"ignore:defusedxml.lxml is no longer supported and will be removed in a future release.:DeprecationWarning",
"ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning",
]
[tool.poetry]
name = "authentik"
version = "2023.1.0"
version = "2023.1.1"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]

View File

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

View File

@ -0,0 +1,165 @@
"""test LDAP Source"""
from typing import Any, Optional
from django.db.models import Q
from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Group, User
from authentik.lib.generators import generate_id, generate_key
from authentik.sources.ldap.auth import LDAPBackend
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
from authentik.sources.ldap.sync.groups import GroupLDAPSynchronizer
from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer
from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
from tests.e2e.utils import SeleniumTestCase, retry
class TestSourceLDAPSamba(SeleniumTestCase):
"""test LDAP Source"""
def setUp(self):
self.admin_password = generate_key()
super().setUp()
def get_container_specs(self) -> Optional[dict[str, Any]]:
return {
"image": "ghcr.io/beryju/test-samba-dc:latest",
"detach": True,
"cap_add": ["SYS_ADMIN"],
"ports": {
"389": "389/tcp",
},
"auto_remove": True,
"environment": {
"SMB_DOMAIN": "test.goauthentik.io",
"SMB_NETBIOS": "goauthentik",
"SMB_ADMIN_PASSWORD": self.admin_password,
},
}
@retry()
@apply_blueprint(
"system/sources-ldap.yaml",
)
def test_source_sync(self):
"""Test Sync"""
source = LDAPSource.objects.create(
name=generate_id(),
slug=generate_id(),
server_uri="ldap://localhost",
bind_cn="administrator@test.goauthentik.io",
bind_password=self.admin_password,
base_dn="dc=test,dc=goauthentik,dc=io",
additional_user_dn="ou=users",
additional_group_dn="ou=groups",
)
source.property_mappings.set(
LDAPPropertyMapping.objects.filter(
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
)
)
source.property_mappings_group.set(
LDAPPropertyMapping.objects.filter(name="goauthentik.io/sources/ldap/default-name")
)
UserLDAPSynchronizer(source).sync()
self.assertTrue(User.objects.filter(username="bob").exists())
self.assertTrue(User.objects.filter(username="james").exists())
self.assertTrue(User.objects.filter(username="john").exists())
self.assertTrue(User.objects.filter(username="harry").exists())
@retry()
@apply_blueprint(
"system/sources-ldap.yaml",
)
def test_source_sync_group(self):
"""Test Sync"""
source = LDAPSource.objects.create(
name=generate_id(),
slug=generate_id(),
server_uri="ldap://localhost",
bind_cn="administrator@test.goauthentik.io",
bind_password=self.admin_password,
base_dn="dc=test,dc=goauthentik,dc=io",
additional_user_dn="ou=users",
additional_group_dn="ou=groups",
)
source.property_mappings.set(
LDAPPropertyMapping.objects.filter(
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
)
)
source.property_mappings_group.set(
LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/default-name")
)
GroupLDAPSynchronizer(source).sync()
UserLDAPSynchronizer(source).sync()
MembershipLDAPSynchronizer(source).sync()
self.assertIsNotNone(User.objects.get(username="bob"))
self.assertIsNotNone(User.objects.get(username="james"))
self.assertIsNotNone(User.objects.get(username="john"))
self.assertIsNotNone(User.objects.get(username="harry"))
self.assertIsNotNone(Group.objects.get(name="dev"))
self.assertEqual(
list(User.objects.get(username="bob").ak_groups.all()), [Group.objects.get(name="dev")]
)
self.assertEqual(list(User.objects.get(username="james").ak_groups.all()), [])
self.assertEqual(
list(User.objects.get(username="john").ak_groups.all().order_by("name")),
[Group.objects.get(name="admins"), Group.objects.get(name="dev")],
)
self.assertEqual(list(User.objects.get(username="harry").ak_groups.all()), [])
@retry()
@apply_blueprint(
"system/sources-ldap.yaml",
)
def test_sync_password(self):
"""Test Sync"""
source = LDAPSource.objects.create(
name=generate_id(),
slug=generate_id(),
server_uri="ldap://localhost",
bind_cn="administrator@test.goauthentik.io",
bind_password=self.admin_password,
base_dn="dc=test,dc=goauthentik,dc=io",
additional_user_dn="ou=users",
additional_group_dn="ou=groups",
)
source.property_mappings.set(
LDAPPropertyMapping.objects.filter(
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
)
)
source.property_mappings_group.set(
LDAPPropertyMapping.objects.filter(name="goauthentik.io/sources/ldap/default-name")
)
UserLDAPSynchronizer(source).sync()
username = "bob"
password = generate_id()
result = self.container.exec_run(
["samba-tool", "user", "setpassword", username, "--newpassword", password]
)
self.assertEqual(result.exit_code, 0)
user: User = User.objects.get(username=username)
# Ensure user has an unusable password directly after sync
self.assertFalse(user.has_usable_password())
# Auth (which will fallback to bind)
LDAPBackend().auth_user(source, password, username=username)
user.refresh_from_db()
# User should now have a usable password in the database
self.assertTrue(user.has_usable_password())
self.assertTrue(user.check_password(password))
# Set new password
new_password = generate_id()
result = self.container.exec_run(
["samba-tool", "user", "setpassword", username, "--newpassword", new_password]
)
self.assertEqual(result.exit_code, 0)
# Sync again
UserLDAPSynchronizer(source).sync()
user.refresh_from_db()
# Since password in samba was checked, it should be invalidated here too
self.assertFalse(user.has_usable_password())

View File

@ -54,7 +54,6 @@ class SeleniumTestCase(StaticLiveServerTestCase):
self.maxDiff = None
self.wait_timeout = 60
self.driver = self._get_driver()
self.driver.maximize_window()
self.driver.implicitly_wait(30)
self.wait = WebDriverWait(self.driver, self.wait_timeout)
self.logger = get_logger()
@ -77,7 +76,9 @@ class SeleniumTestCase(StaticLiveServerTestCase):
def _start_container(self, specs: dict[str, Any]) -> Container:
client: DockerClient = from_env()
container = client.containers.run(**specs)
if "healthcheck" not in specs:
container.reload()
state = container.attrs.get("State", {})
if "Health" not in state:
return container
while True:
container.reload()
@ -100,12 +101,18 @@ class SeleniumTestCase(StaticLiveServerTestCase):
def _get_driver(self) -> WebDriver:
count = 0
try:
return webdriver.Chrome()
except WebDriverException:
pass
while count < RETRIES:
try:
return webdriver.Remote(
driver = webdriver.Remote(
command_executor="http://localhost:4444/wd/hub",
options=webdriver.ChromeOptions(),
)
driver.maximize_window()
return driver
except WebDriverException:
count += 1
raise ValueError(f"Webdriver failed after {RETRIES}.")

264
web/package-lock.json generated
View File

@ -10,7 +10,7 @@
"license": "MIT",
"dependencies": {
"@babel/core": "^7.20.12",
"@babel/plugin-proposal-decorators": "^7.20.7",
"@babel/plugin-proposal-decorators": "^7.20.13",
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
@ -21,18 +21,18 @@
"@codemirror/legacy-modes": "^6.3.1",
"@formatjs/intl-listformat": "^7.1.7",
"@fortawesome/fontawesome-free": "^6.2.1",
"@goauthentik/api": "^2022.12.2-1673978239",
"@goauthentik/api": "^2023.1.0-1674058489",
"@hcaptcha/types": "^1.0.3",
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
"@lingui/cli": "^3.15.0",
"@lingui/core": "^3.15.0",
"@lingui/detect-locale": "^3.15.0",
"@lingui/macro": "^3.15.0",
"@lingui/cli": "^3.16.0",
"@lingui/core": "^3.16.0",
"@lingui/detect-locale": "^3.16.0",
"@lingui/macro": "^3.16.0",
"@patternfly/patternfly": "^4.222.4",
"@polymer/iron-form": "^3.0.1",
"@polymer/paper-input": "^3.2.1",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-typescript": "^11.0.0",
@ -49,11 +49,11 @@
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"base64-js": "^1.5.1",
"chart.js": "^4.1.2",
"chart.js": "^4.2.0",
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.27.1",
"core-js": "^3.27.2",
"country-flag-icons": "^1.5.5",
"eslint": "^8.32.0",
"eslint-config-google": "^0.14.0",
@ -214,9 +214,9 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
"integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
@ -224,6 +224,7 @@
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
"@babel/helper-split-export-declaration": "^7.18.6"
},
"engines": {
@ -410,11 +411,11 @@
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
"integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
"version": "7.20.0",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
"integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
"dependencies": {
"@babel/types": "^7.18.9"
"@babel/types": "^7.20.0"
},
"engines": {
"node": ">=6.9.0"
@ -585,11 +586,11 @@
}
},
"node_modules/@babel/plugin-proposal-decorators": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
"integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
"integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.20.7",
"@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-split-export-declaration": "^7.18.6",
@ -1960,9 +1961,9 @@
}
},
"node_modules/@goauthentik/api": {
"version": "2022.12.2-1673978239",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.12.2-1673978239.tgz",
"integrity": "sha512-VQOn3ySAcjvdeEI5yKbpFQfGD3lh+C1t81SafjwlsDhpFWhbEIaWRyokiw7XYb9b2LyHn3SZTbJjoIhrPEvPow=="
"version": "2023.1.0-1674058489",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.1.0-1674058489.tgz",
"integrity": "sha512-k100Z1Tx4o7EsIq+tezavHSSddpr51NlGJZyR9QHsaQq6K+BpxZVcozR7xau7zK615JAwljWeG4yfEq9to++rw=="
},
"node_modules/@hcaptcha/types": {
"version": "1.0.3",
@ -2214,31 +2215,32 @@
}
},
"node_modules/@lingui/babel-plugin-extract-messages": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.15.0.tgz",
"integrity": "sha512-iMQmJIkC18Zwc/IDpm3Oclj3KMDQuvipCS2yVHr0MyaeOCeOZ3ZoLVeaa8pfE5pImzlHJ0ss8RRm/St54JElhw==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.16.0.tgz",
"integrity": "sha512-Wxfp9cJfVjwhVigufIssoDntaTm4a8XXkmsV9gTMCr2xJL6ZowoC80TltBLOu0Dt829e6pdy+TFuwuKwAvnmrA==",
"dependencies": {
"@babel/generator": "^7.11.6",
"@babel/runtime": "^7.11.2",
"@lingui/conf": "^3.15.0",
"@lingui/conf": "3.16.0",
"mkdirp": "^1.0.4"
},
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@lingui/cli": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.15.0.tgz",
"integrity": "sha512-6arKc0Mc1z3ABHobjPkhViV+7VUjBhwFwoU0VlT7HBmtrOYad9CBwWEiD+oiEhiHYzLTR7lHTVf674IjTuVvJQ==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.16.0.tgz",
"integrity": "sha512-6sUVpA6UB4BwNtLjC9aG62QvxkhHwVmDOi9vO8kb9W4SKPBaMdHuaxEsVVBuD1ZWcFZULcNUmPh9kKAnMRkHHw==",
"dependencies": {
"@babel/generator": "^7.11.6",
"@babel/parser": "^7.11.5",
"@babel/plugin-syntax-jsx": "^7.10.4",
"@babel/runtime": "^7.11.2",
"@babel/types": "^7.11.5",
"@lingui/babel-plugin-extract-messages": "^3.15.0",
"@lingui/conf": "^3.15.0",
"@lingui/babel-plugin-extract-messages": "3.16.0",
"@lingui/conf": "3.16.0",
"@lingui/core": "3.16.0",
"babel-plugin-macros": "^3.0.1",
"bcp-47": "^1.0.7",
"chalk": "^4.1.0",
@ -2251,7 +2253,6 @@
"glob": "^7.1.4",
"inquirer": "^7.3.3",
"make-plural": "^6.2.2",
"messageformat-parser": "^4.1.3",
"micromatch": "4.0.2",
"mkdirp": "^1.0.4",
"node-gettext": "^3.0.0",
@ -2265,10 +2266,10 @@
"ramda": "^0.27.1"
},
"bin": {
"lingui": "lingui.js"
"lingui": "build/lingui.js"
},
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0",
@ -2341,9 +2342,9 @@
}
},
"node_modules/@lingui/conf": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.15.0.tgz",
"integrity": "sha512-gDGBbqWo6+B3PNjxTGl2asVdd8hC6w+iGsEPonvMw7GFmXb99qybBGdV2ofDlwlT9vChcPwMVtrYE6H0fTZuzA==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.16.0.tgz",
"integrity": "sha512-65X3TySGzeYjVNE3YZDpF6LTYxpUiSRSyTJjEGB7ZSPpuL6VDMEUGCDsnur2ix8D+I8w0ife6ks4HPQt6owZmw==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"chalk": "^4.1.0",
@ -2353,7 +2354,7 @@
"lodash.get": "^4.4.2"
},
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@lingui/conf/node_modules/ansi-styles": {
@ -2421,42 +2422,42 @@
}
},
"node_modules/@lingui/core": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.15.0.tgz",
"integrity": "sha512-owjYOn/3xaWVW01p32Ylt3cXkCP79oudJCHdcNOn4noxd/9BhyFX2wLiVf02DxGYnkAgAD3KCp3Z4iyKlueymg==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.16.0.tgz",
"integrity": "sha512-2uZvxHv4IWF7xIRG1o4oXDFCrAhE0945Ses1eALmv/NqQ8BslXWWSq0Zf51qt+ZqQ3RfzCdl4kslZEqdGRe0gw==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"make-plural": "^6.2.2",
"messageformat-parser": "^4.1.3"
"@messageformat/parser": "^5.0.0",
"make-plural": "^6.2.2"
},
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@lingui/detect-locale": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.15.0.tgz",
"integrity": "sha512-+4yLIAyk8asygMGLbR271qHCAT2HQ2AyjljH/xvwMua0sqVX+ES3fwStggJOsCk0zC1yfjMrjV4lAMTPHy5XoA==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.16.0.tgz",
"integrity": "sha512-7FQy1ccPnVe0/GNAzTmEDrsPHZV1/nSsK6fRKyuOFUkiItc1bVDmlpVfM4UXerERx6Nez+N99Z6Vjc6rg3LARw==",
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@lingui/macro": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.15.0.tgz",
"integrity": "sha512-3+txZQM5UmC+t1zkoYeYkg3r5pIGo9KdD+csX0u4F0IUE2GJkjy+sG917hOhw3QsDUqiCIqDJ503AdSfFbO+uA==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.16.0.tgz",
"integrity": "sha512-3HfP1Bqr4i60P3LoQq/ukhDvel4a5oBSMPRuYBUpwqdnKOAbZuN5vnZmu3TrlXntWTYOvrwa71D8SYGmvevelw==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"@lingui/conf": "^3.15.0",
"@lingui/conf": "3.16.0",
"ramda": "^0.27.1"
},
"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"@lingui/core": "^3.13.0",
"@lingui/react": "^3.13.0",
"babel-plugin-macros": "2 || 3"
"babel-plugin-macros": "2 || 3"
}
},
"node_modules/@lingui/react": {
@ -2488,6 +2489,14 @@
"@lit-labs/ssr-dom-shim": "^1.0.0"
}
},
"node_modules/@messageformat/parser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz",
"integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==",
"dependencies": {
"moo": "^0.5.1"
}
},
"node_modules/@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@ -2717,9 +2726,9 @@
}
},
"node_modules/@rollup/plugin-commonjs": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz",
"integrity": "sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==",
"version": "24.0.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
"integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
@ -4218,9 +4227,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"node_modules/chart.js": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.1.2.tgz",
"integrity": "sha512-9L1w6WLPq6ztiWVVOYtDtpo0CUsBKDWPrUEdwChAyzczaikqeSwNKEv3QpJ7EO4ICcLSi6UDVhgvcnUhRJidRA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz",
"integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==",
"dependencies": {
"@kurkle/color": "^0.3.0"
},
@ -4530,9 +4539,9 @@
}
},
"node_modules/core-js": {
"version": "3.27.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz",
"integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==",
"version": "3.27.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@ -7399,11 +7408,6 @@
"uuid": "^9.0.0"
}
},
"node_modules/messageformat-parser": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz",
"integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg=="
},
"node_modules/micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
@ -7483,6 +7487,11 @@
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
"integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ=="
},
"node_modules/moo": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -10209,9 +10218,9 @@
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
"integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
@ -10219,6 +10228,7 @@
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
"@babel/helper-split-export-declaration": "^7.18.6"
}
},
@ -10351,11 +10361,11 @@
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
"integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
"version": "7.20.0",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
"integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
"requires": {
"@babel/types": "^7.18.9"
"@babel/types": "^7.20.0"
}
},
"@babel/helper-split-export-declaration": {
@ -10466,11 +10476,11 @@
}
},
"@babel/plugin-proposal-decorators": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
"integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
"integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
"requires": {
"@babel/helper-create-class-features-plugin": "^7.20.7",
"@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-split-export-declaration": "^7.18.6",
@ -11427,9 +11437,9 @@
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A=="
},
"@goauthentik/api": {
"version": "2022.12.2-1673978239",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.12.2-1673978239.tgz",
"integrity": "sha512-VQOn3ySAcjvdeEI5yKbpFQfGD3lh+C1t81SafjwlsDhpFWhbEIaWRyokiw7XYb9b2LyHn3SZTbJjoIhrPEvPow=="
"version": "2023.1.0-1674058489",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.1.0-1674058489.tgz",
"integrity": "sha512-k100Z1Tx4o7EsIq+tezavHSSddpr51NlGJZyR9QHsaQq6K+BpxZVcozR7xau7zK615JAwljWeG4yfEq9to++rw=="
},
"@hcaptcha/types": {
"version": "1.0.3",
@ -11640,28 +11650,29 @@
}
},
"@lingui/babel-plugin-extract-messages": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.15.0.tgz",
"integrity": "sha512-iMQmJIkC18Zwc/IDpm3Oclj3KMDQuvipCS2yVHr0MyaeOCeOZ3ZoLVeaa8pfE5pImzlHJ0ss8RRm/St54JElhw==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.16.0.tgz",
"integrity": "sha512-Wxfp9cJfVjwhVigufIssoDntaTm4a8XXkmsV9gTMCr2xJL6ZowoC80TltBLOu0Dt829e6pdy+TFuwuKwAvnmrA==",
"requires": {
"@babel/generator": "^7.11.6",
"@babel/runtime": "^7.11.2",
"@lingui/conf": "^3.15.0",
"@lingui/conf": "3.16.0",
"mkdirp": "^1.0.4"
}
},
"@lingui/cli": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.15.0.tgz",
"integrity": "sha512-6arKc0Mc1z3ABHobjPkhViV+7VUjBhwFwoU0VlT7HBmtrOYad9CBwWEiD+oiEhiHYzLTR7lHTVf674IjTuVvJQ==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.16.0.tgz",
"integrity": "sha512-6sUVpA6UB4BwNtLjC9aG62QvxkhHwVmDOi9vO8kb9W4SKPBaMdHuaxEsVVBuD1ZWcFZULcNUmPh9kKAnMRkHHw==",
"requires": {
"@babel/generator": "^7.11.6",
"@babel/parser": "^7.11.5",
"@babel/plugin-syntax-jsx": "^7.10.4",
"@babel/runtime": "^7.11.2",
"@babel/types": "^7.11.5",
"@lingui/babel-plugin-extract-messages": "^3.15.0",
"@lingui/conf": "^3.15.0",
"@lingui/babel-plugin-extract-messages": "3.16.0",
"@lingui/conf": "3.16.0",
"@lingui/core": "3.16.0",
"babel-plugin-macros": "^3.0.1",
"bcp-47": "^1.0.7",
"chalk": "^4.1.0",
@ -11674,7 +11685,6 @@
"glob": "^7.1.4",
"inquirer": "^7.3.3",
"make-plural": "^6.2.2",
"messageformat-parser": "^4.1.3",
"micromatch": "4.0.2",
"mkdirp": "^1.0.4",
"node-gettext": "^3.0.0",
@ -11734,9 +11744,9 @@
}
},
"@lingui/conf": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.15.0.tgz",
"integrity": "sha512-gDGBbqWo6+B3PNjxTGl2asVdd8hC6w+iGsEPonvMw7GFmXb99qybBGdV2ofDlwlT9vChcPwMVtrYE6H0fTZuzA==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.16.0.tgz",
"integrity": "sha512-65X3TySGzeYjVNE3YZDpF6LTYxpUiSRSyTJjEGB7ZSPpuL6VDMEUGCDsnur2ix8D+I8w0ife6ks4HPQt6owZmw==",
"requires": {
"@babel/runtime": "^7.11.2",
"chalk": "^4.1.0",
@ -11792,27 +11802,27 @@
}
},
"@lingui/core": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.15.0.tgz",
"integrity": "sha512-owjYOn/3xaWVW01p32Ylt3cXkCP79oudJCHdcNOn4noxd/9BhyFX2wLiVf02DxGYnkAgAD3KCp3Z4iyKlueymg==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.16.0.tgz",
"integrity": "sha512-2uZvxHv4IWF7xIRG1o4oXDFCrAhE0945Ses1eALmv/NqQ8BslXWWSq0Zf51qt+ZqQ3RfzCdl4kslZEqdGRe0gw==",
"requires": {
"@babel/runtime": "^7.11.2",
"make-plural": "^6.2.2",
"messageformat-parser": "^4.1.3"
"@messageformat/parser": "^5.0.0",
"make-plural": "^6.2.2"
}
},
"@lingui/detect-locale": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.15.0.tgz",
"integrity": "sha512-+4yLIAyk8asygMGLbR271qHCAT2HQ2AyjljH/xvwMua0sqVX+ES3fwStggJOsCk0zC1yfjMrjV4lAMTPHy5XoA=="
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.16.0.tgz",
"integrity": "sha512-7FQy1ccPnVe0/GNAzTmEDrsPHZV1/nSsK6fRKyuOFUkiItc1bVDmlpVfM4UXerERx6Nez+N99Z6Vjc6rg3LARw=="
},
"@lingui/macro": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.15.0.tgz",
"integrity": "sha512-3+txZQM5UmC+t1zkoYeYkg3r5pIGo9KdD+csX0u4F0IUE2GJkjy+sG917hOhw3QsDUqiCIqDJ503AdSfFbO+uA==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.16.0.tgz",
"integrity": "sha512-3HfP1Bqr4i60P3LoQq/ukhDvel4a5oBSMPRuYBUpwqdnKOAbZuN5vnZmu3TrlXntWTYOvrwa71D8SYGmvevelw==",
"requires": {
"@babel/runtime": "^7.11.2",
"@lingui/conf": "^3.15.0",
"@lingui/conf": "3.16.0",
"ramda": "^0.27.1"
}
},
@ -11839,6 +11849,14 @@
"@lit-labs/ssr-dom-shim": "^1.0.0"
}
},
"@messageformat/parser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz",
"integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==",
"requires": {
"moo": "^0.5.1"
}
},
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@ -12031,9 +12049,9 @@
}
},
"@rollup/plugin-commonjs": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz",
"integrity": "sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==",
"version": "24.0.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
"integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
"requires": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
@ -13111,9 +13129,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"chart.js": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.1.2.tgz",
"integrity": "sha512-9L1w6WLPq6ztiWVVOYtDtpo0CUsBKDWPrUEdwChAyzczaikqeSwNKEv3QpJ7EO4ICcLSi6UDVhgvcnUhRJidRA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz",
"integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==",
"requires": {
"@kurkle/color": "^0.3.0"
}
@ -13357,9 +13375,9 @@
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
},
"core-js": {
"version": "3.27.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz",
"integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww=="
"version": "3.27.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w=="
},
"core-js-compat": {
"version": "3.25.1",
@ -15487,11 +15505,6 @@
"uuid": "^9.0.0"
}
},
"messageformat-parser": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz",
"integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg=="
},
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
@ -15550,6 +15563,11 @@
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
"integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ=="
},
"moo": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",

View File

@ -54,7 +54,7 @@
},
"dependencies": {
"@babel/core": "^7.20.12",
"@babel/plugin-proposal-decorators": "^7.20.7",
"@babel/plugin-proposal-decorators": "^7.20.13",
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
@ -65,18 +65,18 @@
"@codemirror/legacy-modes": "^6.3.1",
"@formatjs/intl-listformat": "^7.1.7",
"@fortawesome/fontawesome-free": "^6.2.1",
"@goauthentik/api": "^2022.12.2-1673978239",
"@goauthentik/api": "^2023.1.0-1674058489",
"@hcaptcha/types": "^1.0.3",
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
"@lingui/cli": "^3.15.0",
"@lingui/core": "^3.15.0",
"@lingui/detect-locale": "^3.15.0",
"@lingui/macro": "^3.15.0",
"@lingui/cli": "^3.16.0",
"@lingui/core": "^3.16.0",
"@lingui/detect-locale": "^3.16.0",
"@lingui/macro": "^3.16.0",
"@patternfly/patternfly": "^4.222.4",
"@polymer/iron-form": "^3.0.1",
"@polymer/paper-input": "^3.2.1",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-typescript": "^11.0.0",
@ -93,11 +93,11 @@
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"base64-js": "^1.5.1",
"chart.js": "^4.1.2",
"chart.js": "^4.2.0",
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.27.1",
"core-js": "^3.27.2",
"country-flag-icons": "^1.5.5",
"eslint": "^8.32.0",
"eslint-config-google": "^0.14.0",

View File

@ -1,4 +1,4 @@
Contact: mailto:security@goauthentik.io
Expires: Mon, 1 Jan 2024 00:00 +0200
Preferred-Languages: en, de
Policy: https://github.com/goauthentik/authentik/blob/main/SECURITY.md
Policy: https://goauthentik.io/docs/security/policy

View File

@ -255,7 +255,7 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${t`Exception`}</h3>
<code>${this.event.context.message}</code>
<pre>${this.event.context.message}</pre>
</div>
</div>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
@ -263,7 +263,7 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${t`Exception`}</h3>
<code>${this.event.context.message || this.event.context.error}</code>
<pre>${this.event.context.message || this.event.context.error}</pre>
</div>
<div class="pf-l-flex__item">
<h3>${t`Expression`}</h3>
@ -393,6 +393,13 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
return html`<span>${t`No additional data available.`}</span>`;
}
return this.defaultResponse();
case EventActions.SystemTaskException:
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${t`Exception`}</h3>
<pre>${this.event.context.message}</pre>
</div>
</div>`;
default:
return this.defaultResponse();
}

View File

@ -14,7 +14,20 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { EventsApi, NotificationRule } from "@goauthentik/api";
import { EventsApi, NotificationRule, SeverityEnum } from "@goauthentik/api";
export function SeverityToLabel(severity: SeverityEnum | null | undefined): string {
if (!severity) return t`Unknown severity`;
switch (severity) {
case SeverityEnum.Alert:
return t`Alert`;
case SeverityEnum.Notice:
return t`Notice`;
case SeverityEnum.Warning:
return t`Warning`;
}
return t`Unknown severity`;
}
@customElement("ak-event-rule-list")
export class RuleListPage extends TablePage<NotificationRule> {
@ -80,8 +93,10 @@ export class RuleListPage extends TablePage<NotificationRule> {
row(item: NotificationRule): TemplateResult[] {
return [
html`${item.name}`,
html`${item.severity}`,
html`${item.groupObj?.name || t`None (rule disabled)`}`,
html`${SeverityToLabel(item.severity)}`,
html`${item.groupObj
? html`<a href="#/identity/groups/${item.groupObj.pk}">${item.groupObj.name}</a>`
: t`None (rule disabled)`}`,
html`<ak-forms-modal>
<span slot="submit"> ${t`Update`} </span>
<span slot="header"> ${t`Update Notification Rule`} </span>

View File

@ -61,7 +61,7 @@ export class ExpressionPolicyForm extends ModelForm<ExpressionPolicy, string> {
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">

View File

@ -373,10 +373,10 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
return flow?.pk;
}}
.selected=${(flow: Flow): boolean => {
let selected = this.instance?.enrollmentFlow === flow.pk;
let selected = this.instance?.authenticationFlow === flow.pk;
if (
!this.instance?.pk &&
!this.instance?.enrollmentFlow &&
!this.instance?.authenticationFlow &&
flow.slug === "default-source-authentication"
) {
selected = true;

View File

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

View File

@ -1,5 +1,6 @@
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { PluralCategory } from "make-plural";
import { Messages, i18n } from "@lingui/core";
import { detect, fromNavigator, fromUrl } from "@lingui/detect-locale";
@ -7,7 +8,7 @@ import { t } from "@lingui/macro";
interface Locale {
locale: Messages;
plurals: (n: string | number, ord?: boolean | undefined) => string;
plurals: (n: string | number, ord?: boolean | undefined) => PluralCategory;
}
export const LOCALES: {

View File

@ -160,8 +160,8 @@ export class SearchSelect<T> extends AKElement {
shouldRenderGroups = false;
groupedItems = [["", []]];
}
const renderGroup = (items: T[]): TemplateResult => {
return html`${items.map((obj) => {
const renderGroup = (items: T[], tabIndexStart: number): TemplateResult => {
return html`${items.map((obj, index) => {
let desc = undefined;
if (this.renderDescription) {
desc = this.renderDescription(obj);
@ -177,6 +177,7 @@ export class SearchSelect<T> extends AKElement {
this.selectedObject = obj;
this.open = false;
}}
tabindex=${index + tabIndexStart}
>
${desc === undefined
? this.renderElement(obj)
@ -205,6 +206,7 @@ export class SearchSelect<T> extends AKElement {
role="listbox"
style="max-height:50vh;overflow-y:auto;"
id=${this.dropdownUID}
tabindex="0"
>
${this.blankable
? html`
@ -216,6 +218,7 @@ export class SearchSelect<T> extends AKElement {
this.selectedObject = undefined;
this.open = false;
}}
tabindex="0"
>
${this.emptyOption}
</button>
@ -223,17 +226,17 @@ export class SearchSelect<T> extends AKElement {
`
: html``}
${shouldRenderGroups
? html`${groupedItems.map(([group, items]) => {
? html`${groupedItems.map(([group, items], idx) => {
return html`
<section class="pf-c-dropdown__group">
<h1 class="pf-c-dropdown__group-title">${group}</h1>
<ul>
${renderGroup(items)}
${renderGroup(items, idx)}
</ul>
</section>
`;
})}`
: html`${renderGroup(groupedItems[0][1])}`}
: html`${renderGroup(groupedItems[0][1], 0)}`}
</ul>
</div>`,
this.dropdownContainer,
@ -259,6 +262,11 @@ export class SearchSelect<T> extends AKElement {
this.renderMenu();
}}
@blur=${(ev: FocusEvent) => {
// For Safari, we get the <ul> element itself here when clicking on one of
// it's buttons, as the container has tabindex set
if ((ev.relatedTarget as HTMLElement).id === this.dropdownUID) {
return;
}
// Check if we're losing focus to one of our dropdown items, and if such don't blur
if (ev.relatedTarget instanceof HTMLButtonElement) {
const parentMenu = ev.relatedTarget.closest(

View File

@ -20,6 +20,7 @@ import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
import PFTable from "@patternfly/patternfly/components/Table/table.css";
import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";
import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
@ -153,6 +154,7 @@ export abstract class Table<T> extends AKElement {
PFTable,
PFBullseye,
PFButton,
PFSwitch,
PFToolbar,
PFDropdown,
PFPagination,

View File

@ -11,7 +11,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFSidebar from "@patternfly/patternfly/components/Sidebar/sidebar.css";
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
export abstract class TablePage<T> extends Table<T> {
abstract pageTitle(): string;
@ -19,7 +18,7 @@ export abstract class TablePage<T> extends Table<T> {
abstract pageIcon(): string;
static get styles(): CSSResult[] {
return super.styles.concat(PFPage, PFContent, PFSwitch, PFSidebar);
return super.styles.concat(PFPage, PFContent, PFSidebar);
}
renderSidebarBefore(): TemplateResult {

View File

@ -26,7 +26,7 @@ import "@goauthentik/flow/stages/password/PasswordStage";
import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit";
import { CSSResult, TemplateResult, css, html, render } from "lit";
import { customElement, property } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { until } from "lit/directives/until.js";
@ -458,38 +458,43 @@ export class FlowExecutor extends AKElement implements StageHost {
}
}
renderBackgroundOverlay(): TemplateResult {
const overlaySVG = html`<svg
xmlns="http://www.w3.org/2000/svg"
class="pf-c-background-image__filter"
width="0"
height="0"
style="display:none;"
>
<filter id="image_overlay">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="1.3 0 0 0 0 0 1.3 0 0 0 0 0 1.3 0 0 0 0 0 1 0"
/>
<feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
<feFuncR
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncR>
<feFuncG
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncG>
<feFuncB
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncB>
<feFuncA type="table" tableValues="0 1"></feFuncA>
</feComponentTransfer>
</filter>
</svg>`;
render(overlaySVG, document.body);
return overlaySVG;
}
render(): TemplateResult {
return html`<div class="pf-c-background-image">
<svg
xmlns="http://www.w3.org/2000/svg"
class="pf-c-background-image__filter"
width="0"
height="0"
>
<filter id="image_overlay">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="1.3 0 0 0 0 0 1.3 0 0 0 0 0 1.3 0 0 0 0 0 1 0"
/>
<feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
<feFuncR
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncR>
<feFuncG
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncG>
<feFuncB
type="table"
tableValues="0.086274509803922 0.43921568627451"
></feFuncB>
<feFuncA type="table" tableValues="0 1"></feFuncA>
</feComponentTransfer>
</filter>
</svg>
</div>
return html`<div class="pf-c-background-image">${this.renderBackgroundOverlay()}</div>
<div class="pf-c-page__drawer">
<div class="pf-c-drawer ${this.inspectorOpen ? "pf-m-expanded" : "pf-m-collapsed"}">
<div class="pf-c-drawer__main">

View File

@ -396,9 +396,9 @@ msgstr "Erweiterte Einstellungen"
msgid "Affected model:"
msgstr "Betroffenes Modell:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alarm"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alarm"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "Algorithmus, der zum Signieren der JWT-Token verwendet wird."
@ -2366,6 +2366,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Ausnahme"
@ -3171,6 +3172,10 @@ msgstr "Integrationsschlüssel"
msgid "Intent"
msgstr "Zweck"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4078,6 +4083,7 @@ msgid "Not you?"
msgstr "Nicht Sie?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Hinweis"
@ -6732,6 +6738,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7311,6 +7322,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Warnung"
@ -7411,6 +7423,10 @@ msgstr "Bei der Verbindung zu einem LDAP-Server mit TLS werden Zertifikate stand
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "Bei Verbindung via SSH wird dieses Schlüsselpaar zur Authentifizierung genutzt."
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "Wenn diese Option aktiviert ist, werden die globalen E-Mail Verbindungseinstellungen benutzt und die unten angegebenen Einstellungen ignoriert"

View File

@ -378,9 +378,9 @@ msgstr "Advanced settings"
msgid "Affected model:"
msgstr "Affected model:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alert"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alert"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#~ msgid "Algorithm used to sign the JWT Tokens."
@ -2398,6 +2398,7 @@ msgstr "Example SAML attributes"
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Exception"
@ -3219,6 +3220,10 @@ msgstr "Integration key"
msgid "Intent"
msgstr "Intent"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr "Intercept header authentication"
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr "Internal"
@ -4137,6 +4142,7 @@ msgid "Not you?"
msgstr "Not you?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Notice"
@ -6880,6 +6886,11 @@ msgstr "Unknown provider type"
msgid "Unknown proxy mode"
msgstr "Unknown proxy mode"
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr "Unknown severity"
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr "Unknown type"
@ -7467,6 +7478,7 @@ msgstr "Waiting for authentication..."
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Warning"
@ -7570,6 +7582,10 @@ msgstr "When connecting to an LDAP Server with TLS, certificates are not checked
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "When connecting via SSH, this keypair is used for authentication."
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr "When enabled, authentik will intercept the Authorization header to authenticate the request."
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored."

View File

@ -374,9 +374,9 @@ msgstr "Configuraciones avanzadas"
msgid "Affected model:"
msgstr "Modelo afectado:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alerta"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alerta"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "Algoritmo utilizado para firmar los tokens JWT."
@ -2342,6 +2342,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Excepción"
@ -3145,6 +3146,10 @@ msgstr "Clave de integración"
msgid "Intent"
msgstr "Intención"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4054,6 +4059,7 @@ msgid "Not you?"
msgstr "¿No eres tú?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Notificación"
@ -6708,6 +6714,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7287,6 +7298,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Aviso"
@ -7387,6 +7399,10 @@ msgstr "Al conectarse a un servidor LDAP con TLS, los certificados no se comprue
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "Cuando se conecta a través de SSH, este par de claves se usa para la autenticación."
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "Cuando se habilita, se utilizará la configuración global de conexión de correo electrónico y se ignorarán las configuraciones de conexión que se indican a continuación"

View File

@ -379,9 +379,9 @@ msgstr "Paramètres avancés"
msgid "Affected model:"
msgstr "Modèle affecté :"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alerte"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alerte"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "Algorithme de signature utilisé pour les jetons JWT"
@ -2345,6 +2345,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Exception"
@ -3148,6 +3149,10 @@ msgstr "Clé d'intégration"
msgid "Intent"
msgstr "Intention"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4055,6 +4060,7 @@ msgid "Not you?"
msgstr "Pas vous ?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Note"
@ -6699,6 +6705,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7278,6 +7289,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Avertissement"
@ -7378,6 +7390,10 @@ msgstr ""
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr ""
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "Si activé, les paramètres globaux de connexion email seront utilisés et les paramètres de connexion ci-dessous seront ignorés."

View File

@ -378,9 +378,9 @@ msgstr "Zaawansowane ustawienia"
msgid "Affected model:"
msgstr "Model, którego dotyczy problem:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alert"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alert"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "Algorytm używany do podpisywania tokenów JWT."
@ -2348,6 +2348,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Wyjątek"
@ -3153,6 +3154,10 @@ msgstr "Klucz integracji"
msgid "Intent"
msgstr "Przeznaczenie"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4062,6 +4067,7 @@ msgid "Not you?"
msgstr "Nie ty?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Uwaga"
@ -6718,6 +6724,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7297,6 +7308,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Ostrzeżenie"
@ -7399,6 +7411,10 @@ msgstr "Podczas łączenia się z serwerem LDAP za pomocą TLS, certyfikaty nie
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "Podczas łączenia przez SSH ta para kluczy jest używana do uwierzytelniania."
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "Po włączeniu będą używane globalne ustawienia połączenia poczty e-mail, a poniższe ustawienia połączenia będą ignorowane."

View File

@ -374,9 +374,9 @@ msgstr ""
msgid "Affected model:"
msgstr ""
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr ""
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#~ msgid "Algorithm used to sign the JWT Tokens."
@ -2384,6 +2384,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr ""
@ -3203,6 +3204,10 @@ msgstr ""
msgid "Intent"
msgstr ""
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4119,6 +4124,7 @@ msgid "Not you?"
msgstr ""
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr ""
@ -6850,6 +6856,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7437,6 +7448,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr ""
@ -7538,6 +7550,10 @@ msgstr ""
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr ""
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr ""

View File

@ -374,9 +374,9 @@ msgstr "Gelişmiş ayarlar"
msgid "Affected model:"
msgstr "Etkilenen model:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "Alarm"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "Alarm"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "JWT Belirteçlerini imzalamak için kullanılan algoritma."
@ -2342,6 +2342,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "Hata"
@ -3145,6 +3146,10 @@ msgstr "Entegrasyon anahtarı"
msgid "Intent"
msgstr "Niyet"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4054,6 +4059,7 @@ msgid "Not you?"
msgstr "Sen değil mi?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "Uyarı"
@ -6708,6 +6714,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7287,6 +7298,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "Uyarı"
@ -7387,6 +7399,10 @@ msgstr "TLS ile bir LDAP Sunucusuna bağlanırken, sertifikalar varsayılan olar
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "SSH üzerinden bağlanırken, bu anahtar çifti kimlik doğrulama için kullanılır."
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "Etkinleştirildiğinde, genel E-posta bağlantısı ayarları kullanılır ve aşağıdaki bağlantı ayarları yoksayılır."

View File

@ -380,9 +380,9 @@ msgstr "高级设置"
msgid "Affected model:"
msgstr "受影响的模型:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "注意"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "注意"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "用于签名 JWT 令牌的算法。"
@ -2350,6 +2350,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "异常"
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
msgid "Intent"
msgstr "意图"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4062,6 +4067,7 @@ msgid "Not you?"
msgstr "不是您?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "通知"
@ -6716,6 +6722,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7295,6 +7306,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "警告"
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "启用后,将使用全局电子邮件连接设置,下面的连接设置将被忽略。"

View File

@ -380,9 +380,9 @@ msgstr "高级设置"
msgid "Affected model:"
msgstr "受影响的模型:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "注意"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "注意"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "用于对JWT令牌进行签名的算法。"
@ -2350,6 +2350,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "例外"
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
msgid "Intent"
msgstr "意图"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4062,6 +4067,7 @@ msgid "Not you?"
msgstr "不是你?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "注意"
@ -6716,6 +6722,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7295,6 +7306,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "警告"
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "启用后,将使用全局电子邮件连接设置,而下面的连接设置将被忽略。"

View File

@ -380,9 +380,9 @@ msgstr "高级设置"
msgid "Affected model:"
msgstr "受影响的模型:"
#: src/admin/events/RuleForm.ts
#~ msgid "Alert"
#~ msgstr "注意"
#: src/admin/events/RuleListPage.ts
msgid "Alert"
msgstr "注意"
#~ msgid "Algorithm used to sign the JWT Tokens."
#~ msgstr "用于对JWT令牌进行签名的算法。"
@ -2350,6 +2350,7 @@ msgstr ""
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
#: src/admin/events/EventInfo.ts
msgid "Exception"
msgstr "例外"
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
msgid "Intent"
msgstr "意图"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "Intercept header authentication"
msgstr ""
#: src/admin/blueprints/BlueprintForm.ts
msgid "Internal"
msgstr ""
@ -4062,6 +4067,7 @@ msgid "Not you?"
msgstr "不是你?"
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
msgid "Notice"
msgstr "注意"
@ -6716,6 +6722,11 @@ msgstr ""
msgid "Unknown proxy mode"
msgstr ""
#: src/admin/events/RuleListPage.ts
#: src/admin/events/RuleListPage.ts
msgid "Unknown severity"
msgstr ""
#: src/admin/outposts/OutpostListPage.ts
msgid "Unknown type"
msgstr ""
@ -7295,6 +7306,7 @@ msgstr ""
#: src/admin/admin-overview/cards/SystemStatusCard.ts
#: src/admin/blueprints/BlueprintListPage.ts
#: src/admin/events/RuleForm.ts
#: src/admin/events/RuleListPage.ts
#: src/admin/system-tasks/SystemTaskListPage.ts
msgid "Warning"
msgstr "警告"
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
msgid "When connecting via SSH, this keypair is used for authentication."
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
#: src/admin/providers/proxy/ProxyProviderForm.ts
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
msgstr ""
#: src/admin/stages/email/EmailStageForm.ts
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "启用后,将使用全局电子邮件连接设置,而下面的连接设置将被忽略。"

View File

@ -8,4 +8,4 @@ The following stages are supported:
- [**identification**](../stages/identification/)
- [**password**](../stages/password/)
- [**authenticator_validate**](../stages/authenticator_validate/) (currently only DUO devices are supported)
- [**authenticator_validate**](../stages/authenticator_validate/)

View File

@ -53,3 +53,32 @@ Requires authentik 2022.6
:::
To only verify the validity of a users' phone number, without saving it in an easily accessible way, you can enable this option. Phone numbers from devices enrolled through this stage will only have their hashed phone number saved. These devices can also not be used with the [Authenticator validation](../authenticator_validate/) stage.
## Limiting phone numbers
To limit phone numbers (for example to a specific region code), you can create an expression policy to validate the phone number, and use a prompt stage for input.
### Expression policy
Create an expression policy to check the phone number:
```python
# Trim all whitespace in and around the user input
phone_number = regex_replace(request.context["prompt_data"]["phone"], r'\s+', '')
# Only allow a specific region code
if phone_number.startswith("+1234"):
return True
ak_message("Invalid phone number or missing region code")
return False
```
### Prompt stage
Create a text prompt field with the _field key_ set to `phone`. Make sure it is selected as a required field.
Create a prompt stage with the phone field you created above, and select the expression policy created above as validation policy.
### Flow
Create a new flow to enroll SMS devices. Bind the prompt stage created above as first stage, and create/bind a _SMS Authenticator Setup Stage_, and bind it to the flow as second stage. This stage will see the `phone` field in the flow's context's `prompt_data`, and not prompt the user for a phone number.

View File

@ -26,6 +26,8 @@ AUTHENTIK_TAG=gh-next
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
```
The beta image is amd64 only. For arm64 platforms, append `-arm64` to the tag name.
Afterwards, run the upgrade commands from the latest release notes.
</TabItem>
@ -43,6 +45,8 @@ image:
pullPolicy: Always
```
The beta image is amd64 only. For arm64 platforms, append `-arm64` to the tag name.
Afterwards, run the upgrade commands from the latest release notes.
</TabItem>

View File

@ -11,7 +11,7 @@ title: Generic Setup
2. Create a new group for LDAP searches. In this example `ldapsearch`. Add the `ldapservice` user to this new group.
:::info
Note: The `default-authentication-flow` validates MFA by default, and currently only Duo-based MFA devices are supported by LDAP. If you plan to use only dedicated service accounts to bind to LDAP, then you can use the default flow and skip the extra steps below and continue at [Create LDAP Provider](#create-ldap-provider)
Note: The `default-authentication-flow` validates MFA by default, and currently everything but SMS-based devices are supported by LDAP. If you plan to use only dedicated service accounts to bind to LDAP, or don't use SMS-based authenticators, then you can use the default flow and skip the extra steps below and continue at [Create LDAP Provider](#create-ldap-provider)
:::
### LDAP Flow

View File

@ -78,6 +78,10 @@ The following stages are supported:
SMS-based authenticators are not supported as they require a code to be sent from authentik, which is not possible during the bind.
- [User Logout](../../flow/stages/user_logout.md)
- [User Login](../../flow/stages/user_login.md)
- [Deny](../../flow/stages/deny.md)
#### Direct bind
In this mode, the outpost will always execute the configured flow when a new bind request is received.

View File

@ -93,6 +93,28 @@ image:
- web/elements: fix pagination page button colours in dark mode
- web/elements: use correct Action Label for user related events
## Fixed in 2023.1.1
- add tests to prevent empty SAN
- blueprints: fix OOB email field overwriting user settings email field
- ci: build beta for amd64 and arm64 (#4468)
- crypto: ensure we don't generate an empty SAN certificate
- crypto: fallback when no SAN values are given
- outposts/ldap: fix queries filtering objectClass with non-lowercase values
- outposts/proxy: fix panic due to IsSet misbehaving
- providers/oauth2: more x5c and ecdsa x/y tests (#4463)
- providers/proxy: fix issuer for embedded outpost (#4480)
- sources/ldap: add e2e LDAP source tests (#4462)
- stages: always use get_pending_user instead of getting context user
- stages/authenticator_sms: fix code not being sent when phone_number is in context
- web/admin: don't enable execution logging by default
- web/admin: improve display of rule severity
- web/admin: improve display of system task exception
- web/admin: link group of notification rule
- web/elements: fix pf-c-switch not rendering correctly in pure tables
- web/elements: fix SearchSelect not working on safari
- web/flows: fix flow executor background overlay in safari
## API Changes
#### What's Deleted

View File

@ -52,7 +52,7 @@ import TabItem from "@theme/TabItem";
OPENID_AUTHORIZATION_ENDPOINT: https://authentik.company/application/o/authorize/
OPENID_CLIENT_ID: # client ID from above
OPENID_ISSUER: https://authentik.company/application/o/*Slug of the application from above*/
OPENID_JWKS_ENDPOINT: https://authentik.company/application/o/*Slug of the application from above*/jwks/
OPENID_JWKS_ENDPOINT: https://authentik.company/application/o/*Slug of the application from above*/jwks/?exclude_x5
OPENID_REDIRECT_URI: https://guacamole.company/ # This must match the redirect URI above
```
@ -64,7 +64,7 @@ OPENID_REDIRECT_URI: https://guacamole.company/ # This must match the redirect U
openid-authorization-endpoint=https://authentik.company/application/o/authorize/
openid-client-id=# client ID from above
openid-issuer=https://authentik.company/application/o/*Slug of the application from above*/
openid-jwks-endpoint=https://authentik.company/application/o/*Slug of the application from above*/jwks/
openid-jwks-endpoint=https://authentik.company/application/o/*Slug of the application from above*/jwks/?exclude_x5
openid-redirect-uri=https://guacamole.company/ # This must match the redirect URI above
```

View File

@ -220,13 +220,14 @@ module.exports = {
description: "Release notes for recent authentik versions",
},
items: [
"releases/2023/v2023.1",
"releases/2022/v2022.12",
"releases/2022/v2022.11",
"releases/2022/v2022.10",
{
type: "category",
label: "Previous versions",
items: [
"releases/2022/v2022.10",
"releases/2022/v2022.9",
"releases/2022/v2022.8",
"releases/2022/v2022.7",