Compare commits

...

63 Commits

Author SHA1 Message Date
2d5c45543b release: 2021.5.4 2021-05-22 20:15:23 +02:00
9d476a42d1 web: don't set X-Forwarded-Proto when no request TLS Options are set
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-22 19:46:40 +02:00
2c816e6162 providers/proxy: don't use https to communicate with outpost
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-22 18:56:38 +02:00
dbcb4d46ba web: fix missing flow and policy cache UI
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-22 13:04:13 +02:00
6600da7d98 providers/oauth2: add missing kid header to JWT Tokens
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 23:40:00 +02:00
a265dd54cc stages/authenticator_*: fix Permission Error when disabling Authenticator as non-superuser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 21:25:03 +02:00
a603f42cc0 api: add OwnerFilter
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 20:46:59 +02:00
d9a788aac8 api: rename auth to authentication, add authorization for rest_framework permission class
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 20:14:03 +02:00
7c6185b581 api: fix URL names for admin Authenticator Views
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 19:53:40 +02:00
41a1305555 policies: improve debug logging
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 19:10:47 +02:00
75f252b530 flows: rename oob to oobe
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 19:10:42 +02:00
a9519a4a68 g: set x-forwarded-proto based on upstream TLS Status
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-21 09:41:39 +02:00
bf4cbb25fe release: 2021.5.3 2021-05-20 20:17:39 +02:00
a925418f60 lib: don't send ImproperlyConfigured to sentry
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 19:18:35 +02:00
ffd61d0e60 root: fix bumpversion
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 19:16:23 +02:00
71d112bdcf sources/plex: remove default for plex_token
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 19:13:54 +02:00
c58fe18b97 web: remove nginx config, add caching headers to g
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 19:11:55 +02:00
590c7f4c9d outposts: fix error on outpost disconnect
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 18:07:27 +02:00
56f1204c9b outposts: fix update signal not being sent to correct instances
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 15:23:38 +02:00
349a5b2d00 web/admin: fix flow form not loading data
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 01:10:19 +02:00
63e3667e82 web: fix t.reset is not a function
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 01:10:11 +02:00
92f2a82c03 providers/oauth2: fix double login required when prompt=login
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 01:10:08 +02:00
dcf074650e providers/proxy: fix redirect_uris not always being set on save
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-20 01:10:04 +02:00
5a465fbc36 release: 2021.5.2 2021-05-17 19:54:10 +02:00
7cd80a903a build(deps): bump eslint-plugin-lit from 1.4.0 to 1.4.1 in /web (#890)
Bumps [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/43081j/eslint-plugin-lit/releases)
- [Commits](https://github.com/43081j/eslint-plugin-lit/compare/v1.4.0...v1.4.1)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-17 09:12:14 +02:00
dd00351bc7 build(deps): bump rollup from 2.47.0 to 2.48.0 in /web (#889)
Bumps [rollup](https://github.com/rollup/rollup) from 2.47.0 to 2.48.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.47.0...v2.48.0)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-17 09:12:05 +02:00
5fca7d11b8 build(deps): bump boto3 from 1.17.72 to 1.17.73 (#891)
Bumps [boto3](https://github.com/boto/boto3) from 1.17.72 to 1.17.73.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.17.72...1.17.73)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-17 09:08:53 +02:00
0ff59636f7 build(deps-dev): bump pytest-django from 4.2.0 to 4.3.0 (#892)
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.2.0...v4.3.0)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-17 09:08:41 +02:00
e5ebe390d2 ci: fix missing dependencies for scripts.generate_ci_config
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-17 00:08:45 +02:00
b66626f9c4 ci: generate secert_key for CI runs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 23:46:23 +02:00
23123c43ee website/docs: improve wording on release notes, point to tag for docker-compose download
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 23:08:11 +02:00
8ce918d527 website/docs: Always point to master copy of docker-compose.yml in installation instructions (#888) 2021-05-16 23:02:16 +02:00
45c1a603e7 root: fix linting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 22:29:28 +02:00
583271d5ed root: only load debug secret key when debug is enabled
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 22:25:55 +02:00
176360fdd7 website/docs: fix $auth_cookie not being defined in outpost docs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 22:18:31 +02:00
8d2a3b67b9 lib: Fix config loading of secrets from files (#887) 2021-05-16 21:10:31 +02:00
d0d3072c50 outposts/ldap: fix AUTHENTIK_INSECURE not being respected for API client during bind
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-16 00:01:16 +02:00
34e2bbc41d Merge branch 'next' 2021-05-15 23:25:17 +02:00
ea2dbb2f33 web/admin: fix error when copying token while none exist
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 23:25:06 +02:00
c55f2ad10a root: set additional sentry tags
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 19:53:43 +02:00
2cde40aeee website/docs: add release notes for 2021.5.2
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 17:49:34 +02:00
a30b32fbbf outposts: fix missing default for OutpostState.for_channel
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 17:46:53 +02:00
1745306cc6 outposts: fix error when controller loads from cache but cache has expired
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 17:45:33 +02:00
8925787a13 flows: fix error when using cancel flow
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 17:42:37 +02:00
968b7ec17a lib: fix parsing of remote IP header when behind multiple reverse proxies
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 15:08:53 +02:00
6600d5bf69 providers/oauth2: use user.uid
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 14:08:49 +02:00
a4278833d8 providers/proxy: fix ingress not being created with full https
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-15 13:45:41 +02:00
942905b9b1 providers/proxy: fix formatting issue
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 16:24:35 +02:00
81056c3889 LDAP: use username instead of name for user dn (#883) 2021-05-14 12:58:27 +02:00
36b694fc41 website/docs: add example ldapsearch command
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:47:38 +02:00
2d9f216658 web/admin: add notice for LDAP Provider's group selection
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:44:01 +02:00
8d7bb7da17 providers/proxy: connect ingress to https instead of http
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#882
2021-05-14 11:42:03 +02:00
965db6eaf5 outposts/proxy: fix insecure TLS Skip
closes #882

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:38:40 +02:00
9bdd6f23a4 website/docs: add ldap example, use ghcr
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:19:09 +02:00
675ad7710c outposts/proxy: fix error redeeming code when using non-standard ports
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:13:57 +02:00
9939db13c3 outposts: fix reload notification not working due to wrong ID being saved
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 11:13:04 +02:00
03e134b296 web/admin: fix propertymappings not loading correctly
closes #879

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 10:58:33 +02:00
465750276c core: fix application's slug field not being set to unique
closes #881

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 10:49:42 +02:00
9b13191646 web: fix chunks overwriting each other
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 01:06:29 +02:00
634ea61b50 lifecycle: check if group of docker socket exists
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-14 00:50:20 +02:00
0fcb4936a2 web: output js chunks without hashing
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 23:15:40 +02:00
934e62d5be lifecycle: fix error when worker is not running as root
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 22:55:35 +02:00
c5e9197b19 website/docs: fix release notes
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 21:43:10 +02:00
99 changed files with 808 additions and 703 deletions

View File

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 2021.5.1 current_version = 2021.5.4
tag = True tag = True
commit = True commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*) parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*)
@ -31,8 +31,6 @@ values =
[bumpversion:file:web/src/constants.ts] [bumpversion:file:web/src/constants.ts]
[bumpversion:file:web/nginx.conf]
[bumpversion:file:website/docs/outposts/manual-deploy-docker-compose.md] [bumpversion:file:website/docs/outposts/manual-deploy-docker-compose.md]
[bumpversion:file:website/docs/outposts/manual-deploy-kubernetes.md] [bumpversion:file:website/docs/outposts/manual-deploy-kubernetes.md]

View File

@ -36,9 +36,9 @@ jobs:
with: with:
push: ${{ github.event_name == 'release' }} push: ${{ github.event_name == 'release' }}
tags: | tags: |
beryju/authentik:2021.5.1, beryju/authentik:2021.5.4,
beryju/authentik:latest, beryju/authentik:latest,
ghcr.io/goauthentik/server:2021.5.1, ghcr.io/goauthentik/server:2021.5.4,
ghcr.io/goauthentik/server:latest ghcr.io/goauthentik/server:latest
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
context: . context: .
@ -75,9 +75,9 @@ jobs:
with: with:
push: ${{ github.event_name == 'release' }} push: ${{ github.event_name == 'release' }}
tags: | tags: |
beryju/authentik-proxy:2021.5.1, beryju/authentik-proxy:2021.5.4,
beryju/authentik-proxy:latest, beryju/authentik-proxy:latest,
ghcr.io/goauthentik/proxy:2021.5.1, ghcr.io/goauthentik/proxy:2021.5.4,
ghcr.io/goauthentik/proxy:latest ghcr.io/goauthentik/proxy:latest
context: outpost/ context: outpost/
file: outpost/proxy.Dockerfile file: outpost/proxy.Dockerfile
@ -115,9 +115,9 @@ jobs:
with: with:
push: ${{ github.event_name == 'release' }} push: ${{ github.event_name == 'release' }}
tags: | tags: |
beryju/authentik-ldap:2021.5.1, beryju/authentik-ldap:2021.5.4,
beryju/authentik-ldap:latest, beryju/authentik-ldap:latest,
ghcr.io/goauthentik/ldap:2021.5.1, ghcr.io/goauthentik/ldap:2021.5.4,
ghcr.io/goauthentik/ldap:latest ghcr.io/goauthentik/ldap:latest
context: outpost/ context: outpost/
file: outpost/ldap.Dockerfile file: outpost/ldap.Dockerfile
@ -155,5 +155,5 @@ jobs:
SENTRY_PROJECT: authentik SENTRY_PROJECT: authentik
SENTRY_URL: https://sentry.beryju.org SENTRY_URL: https://sentry.beryju.org
with: with:
version: authentik@2021.5.1 version: authentik@2021.5.4
environment: beryjuorg-prod environment: beryjuorg-prod

120
Pipfile.lock generated
View File

@ -56,7 +56,6 @@
"sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a", "sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a",
"sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95" "sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95"
], ],
"markers": "python_version >= '3.6'",
"version": "==3.7.4.post0" "version": "==3.7.4.post0"
}, },
"aioredis": { "aioredis": {
@ -71,7 +70,6 @@
"sha256:03e16e94f2b34c31f8bf1206d8ddd3ccaa4c315f7f6a1879b7b1210d229568c2", "sha256:03e16e94f2b34c31f8bf1206d8ddd3ccaa4c315f7f6a1879b7b1210d229568c2",
"sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb" "sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb"
], ],
"markers": "python_version >= '3.6'",
"version": "==5.0.6" "version": "==5.0.6"
}, },
"asgiref": { "asgiref": {
@ -79,7 +77,6 @@
"sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee", "sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee",
"sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78" "sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78"
], ],
"markers": "python_version >= '3.6'",
"version": "==3.3.4" "version": "==3.3.4"
}, },
"async-timeout": { "async-timeout": {
@ -87,7 +84,6 @@
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
], ],
"markers": "python_full_version >= '3.5.3'",
"version": "==3.0.1" "version": "==3.0.1"
}, },
"attrs": { "attrs": {
@ -95,7 +91,6 @@
"sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1",
"sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==21.2.0" "version": "==21.2.0"
}, },
"autobahn": { "autobahn": {
@ -103,7 +98,6 @@
"sha256:9195df8af03b0ff29ccd4b7f5abbde957ee90273465942205f9a1bad6c3f07ac", "sha256:9195df8af03b0ff29ccd4b7f5abbde957ee90273465942205f9a1bad6c3f07ac",
"sha256:e126c1f583e872fb59e79d36977cfa1f2d0a8a79f90ae31f406faae7664b8e03" "sha256:e126c1f583e872fb59e79d36977cfa1f2d0a8a79f90ae31f406faae7664b8e03"
], ],
"markers": "python_version >= '3.7'",
"version": "==21.3.1" "version": "==21.3.1"
}, },
"automat": { "automat": {
@ -122,25 +116,24 @@
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:3317722a1e9acbfc0d30cdf273d1708c823ceb19309e9cd91cac8a3604762341", "sha256:13cfe0e3ae1bdc7baf4272b1814a7e760fbb508b19d6ac3f472a6bbd64baad61",
"sha256:ee3317fd79b443ef102469fac393a1ffb650ea51ac4fc27464013872c5e1ce31" "sha256:ce08b88a2d7a0ad8edb385f84ea4914296fee6813c66ebf0def956d5278de793"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.17.72" "version": "==1.17.73"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:0fa93a2e2daad5791c63ee526ada66896cc483d04cb2d32bfcadfeb881203453" "sha256:4b4aa58c61d4b125bc6ec1597924b2749e19de8f2c9a374ac087aa2561e71828",
"sha256:69dc0b6fdc0855f5a4f8b1d29c96b9cec44e71054fea0f968e5904d6ccfd4fd9"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.20.73"
"version": "==1.20.72"
}, },
"cachetools": { "cachetools": {
"hashes": [ "hashes": [
"sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001", "sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001",
"sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff" "sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff"
], ],
"markers": "python_version ~= '3.5'",
"version": "==4.2.2" "version": "==4.2.2"
}, },
"cbor2": { "cbor2": {
@ -227,7 +220,6 @@
"sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa",
"sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==4.0.0" "version": "==4.0.0"
}, },
"click": { "click": {
@ -235,7 +227,6 @@
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==7.1.2" "version": "==7.1.2"
}, },
"click-didyoumean": { "click-didyoumean": {
@ -309,7 +300,6 @@
"sha256:76ffae916ba3aa66b46996c14fa713e46004788167a4873d647544e750e0e99f", "sha256:76ffae916ba3aa66b46996c14fa713e46004788167a4873d647544e750e0e99f",
"sha256:a9af943c79717bc52fe64a3c236ae5d3adccc8b5be19c881b442d2c3db233393" "sha256:a9af943c79717bc52fe64a3c236ae5d3adccc8b5be19c881b442d2c3db233393"
], ],
"markers": "python_version >= '3.6'",
"version": "==3.0.2" "version": "==3.0.2"
}, },
"defusedxml": { "defusedxml": {
@ -330,9 +320,6 @@
}, },
"django-dbbackup": { "django-dbbackup": {
"git": "https://github.com/django-dbbackup/django-dbbackup.git", "git": "https://github.com/django-dbbackup/django-dbbackup.git",
"hashes": [
"sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8"
],
"ref": "9d1909c30a3271c8c9c8450add30d6e0b996e145" "ref": "9d1909c30a3271c8c9c8450add30d6e0b996e145"
}, },
"django-filter": { "django-filter": {
@ -435,7 +422,6 @@
"hashes": [ "hashes": [
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.18.2" "version": "==0.18.2"
}, },
"geoip2": { "geoip2": {
@ -451,7 +437,6 @@
"sha256:588bdb03a41ecb4978472b847881e5518b5d9ec6153d3d679aa127a55e13b39f", "sha256:588bdb03a41ecb4978472b847881e5518b5d9ec6153d3d679aa127a55e13b39f",
"sha256:9ad25fba07f46a628ad4d0ca09f38dcb262830df2ac95b217f9b0129c9e42206" "sha256:9ad25fba07f46a628ad4d0ca09f38dcb262830df2ac95b217f9b0129c9e42206"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.30.0" "version": "==1.30.0"
}, },
"gunicorn": { "gunicorn": {
@ -467,7 +452,6 @@
"sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6", "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6",
"sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042" "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"
], ],
"markers": "python_version >= '3.6'",
"version": "==0.12.0" "version": "==0.12.0"
}, },
"hiredis": { "hiredis": {
@ -514,7 +498,6 @@
"sha256:f52010e0a44e3d8530437e7da38d11fb822acfb0d5b12e9cd5ba655509937ca0", "sha256:f52010e0a44e3d8530437e7da38d11fb822acfb0d5b12e9cd5ba655509937ca0",
"sha256:f8196f739092a78e4f6b1b2172679ed3343c39c61a3e9d722ce6fcf1dac2824a" "sha256:f8196f739092a78e4f6b1b2172679ed3343c39c61a3e9d722ce6fcf1dac2824a"
], ],
"markers": "python_version >= '3.6'",
"version": "==2.0.0" "version": "==2.0.0"
}, },
"httptools": { "httptools": {
@ -563,7 +546,6 @@
"sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417",
"sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2" "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"
], ],
"markers": "python_version >= '3.5'",
"version": "==0.5.1" "version": "==0.5.1"
}, },
"itypes": { "itypes": {
@ -578,7 +560,6 @@
"sha256:2f2de5285cf37f33d33ecd4a9080b75c87cd0c1994d5a9c6df17131ea1f049c6", "sha256:2f2de5285cf37f33d33ecd4a9080b75c87cd0c1994d5a9c6df17131ea1f049c6",
"sha256:ea8d7dd814ce9df6de6a761ec7f1cac98afe305b8cdc4aaae4e114b8d8ce24c5" "sha256:ea8d7dd814ce9df6de6a761ec7f1cac98afe305b8cdc4aaae4e114b8d8ce24c5"
], ],
"markers": "python_version >= '3.6'",
"version": "==3.0.0" "version": "==3.0.0"
}, },
"jmespath": { "jmespath": {
@ -586,7 +567,6 @@
"sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9",
"sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.0" "version": "==0.10.0"
}, },
"jsonschema": { "jsonschema": {
@ -601,7 +581,6 @@
"sha256:6dc509178ac4269b0e66ab4881f70a2035c33d3a622e20585f965986a5182006", "sha256:6dc509178ac4269b0e66ab4881f70a2035c33d3a622e20585f965986a5182006",
"sha256:f4965fba0a4718d47d470beeb5d6446e3357a62402b16c510b6a2f251e05ac3c" "sha256:f4965fba0a4718d47d470beeb5d6446e3357a62402b16c510b6a2f251e05ac3c"
], ],
"markers": "python_version >= '3.6'",
"version": "==5.0.2" "version": "==5.0.2"
}, },
"kubernetes": { "kubernetes": {
@ -614,11 +593,8 @@
}, },
"ldap3": { "ldap3": {
"hashes": [ "hashes": [
"sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57",
"sha256:18c3ee656a6775b9b0d60f7c6c5b094d878d1d90fc03d56731039f0a4b546a91", "sha256:18c3ee656a6775b9b0d60f7c6c5b094d878d1d90fc03d56731039f0a4b546a91",
"sha256:8c949edbad2be8a03e719ba48bd6779f327ec156929562814b3e84ab56889c8c", "sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57"
"sha256:afc6fc0d01f02af82cd7bfabd3bbfd5dc96a6ae91e97db0a2dab8a0f1b436056",
"sha256:4139c91f0eef9782df7b77c8cbc6243086affcb6a8a249b768a9658438e5da59"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.9" "version": "==2.9"
@ -712,14 +688,12 @@
"sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf", "sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf",
"sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b" "sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b"
], ],
"markers": "python_version >= '3.6'",
"version": "==2.0.0" "version": "==2.0.0"
}, },
"maxminddb": { "maxminddb": {
"hashes": [ "hashes": [
"sha256:47e86a084dd814fac88c99ea34ba3278a74bc9de5a25f4b815b608798747c7dc" "sha256:47e86a084dd814fac88c99ea34ba3278a74bc9de5a25f4b815b608798747c7dc"
], ],
"markers": "python_version >= '3.6'",
"version": "==2.0.3" "version": "==2.0.3"
}, },
"msgpack": { "msgpack": {
@ -795,7 +769,6 @@
"sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281",
"sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80"
], ],
"markers": "python_version >= '3.6'",
"version": "==5.1.0" "version": "==5.1.0"
}, },
"oauthlib": { "oauthlib": {
@ -803,7 +776,6 @@
"sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889", "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889",
"sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea" "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==3.1.0" "version": "==3.1.0"
}, },
"packaging": { "packaging": {
@ -819,7 +791,6 @@
"sha256:030e4f9df5f53db2292eec37c6255957eb76168c6f974e4176c711cf91ed34aa", "sha256:030e4f9df5f53db2292eec37c6255957eb76168c6f974e4176c711cf91ed34aa",
"sha256:b6c5a9643e3545bcbfd9451766cbaa5d9c67e7303c7bc32c750b6fa70ecb107d" "sha256:b6c5a9643e3545bcbfd9451766cbaa5d9c67e7303c7bc32c750b6fa70ecb107d"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.1" "version": "==0.10.1"
}, },
"prompt-toolkit": { "prompt-toolkit": {
@ -827,7 +798,6 @@
"sha256:bf00f22079f5fadc949f42ae8ff7f05702826a97059ffcc6281036ad40ac6f04", "sha256:bf00f22079f5fadc949f42ae8ff7f05702826a97059ffcc6281036ad40ac6f04",
"sha256:e1b4f11b9336a28fa11810bc623c357420f69dfdb6d2dac41ca2c21a55c033bc" "sha256:e1b4f11b9336a28fa11810bc623c357420f69dfdb6d2dac41ca2c21a55c033bc"
], ],
"markers": "python_full_version >= '3.6.1'",
"version": "==3.0.18" "version": "==3.0.18"
}, },
"psycopg2-binary": { "psycopg2-binary": {
@ -873,37 +843,15 @@
}, },
"pyasn1": { "pyasn1": {
"hashes": [ "hashes": [
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf",
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776",
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3",
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba",
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"
], ],
"version": "==0.4.8" "version": "==0.4.8"
}, },
"pyasn1-modules": { "pyasn1-modules": {
"hashes": [ "hashes": [
"sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd",
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45",
"sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4",
"sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d",
"sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0",
"sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811",
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8",
"sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e",
"sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"
"sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb",
"sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405",
"sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed",
"sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"
], ],
"version": "==0.2.8" "version": "==0.2.8"
}, },
@ -912,7 +860,6 @@
"sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0",
"sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.20" "version": "==2.20"
}, },
"pycryptodome": { "pycryptodome": {
@ -956,7 +903,6 @@
"sha256:412e00137858f04bde0729913874a48485665f2d36fe9ee449f26be864af9316", "sha256:412e00137858f04bde0729913874a48485665f2d36fe9ee449f26be864af9316",
"sha256:7ead136e03655af85069b6f47b23eb7c3e5c221aa9f022a4fbb499f5b7308f29" "sha256:7ead136e03655af85069b6f47b23eb7c3e5c221aa9f022a4fbb499f5b7308f29"
], ],
"markers": "python_version >= '3.5'",
"version": "==2.0.2" "version": "==2.0.2"
}, },
"pyjwt": { "pyjwt": {
@ -979,14 +925,12 @@
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7" "version": "==2.4.7"
}, },
"pyrsistent": { "pyrsistent": {
"hashes": [ "hashes": [
"sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"
], ],
"markers": "python_version >= '3.5'",
"version": "==0.17.3" "version": "==0.17.3"
}, },
"python-dateutil": { "python-dateutil": {
@ -994,7 +938,6 @@
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.8.1" "version": "==2.8.1"
}, },
"python-dotenv": { "python-dotenv": {
@ -1051,7 +994,6 @@
"sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2", "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2",
"sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24" "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==3.5.3" "version": "==3.5.3"
}, },
"requests": { "requests": {
@ -1059,14 +1001,12 @@
"sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
"sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.25.1" "version": "==2.25.1"
}, },
"requests-oauthlib": { "requests-oauthlib": {
"hashes": [ "hashes": [
"sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d", "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d",
"sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a", "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"
"sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.3.0" "version": "==1.3.0"
@ -1084,7 +1024,6 @@
"sha256:44bc6b54fddd45e4bc0619059196679f9e8b79c027f4131bb072e6a22f4d5e28", "sha256:44bc6b54fddd45e4bc0619059196679f9e8b79c027f4131bb072e6a22f4d5e28",
"sha256:ac79fb25f5476e8e9ed1c53b8a2286d2c3f5dde49eb37dbcee5c7eb6a8415a22" "sha256:ac79fb25f5476e8e9ed1c53b8a2286d2c3f5dde49eb37dbcee5c7eb6a8415a22"
], ],
"markers": "python_version >= '3'",
"version": "==0.17.4" "version": "==0.17.4"
}, },
"ruamel.yaml.clib": { "ruamel.yaml.clib": {
@ -1121,7 +1060,7 @@
"sha256:e9f7d1d8c26a6a12c23421061f9022bb62704e38211fe375c645485f38df34a2", "sha256:e9f7d1d8c26a6a12c23421061f9022bb62704e38211fe375c645485f38df34a2",
"sha256:f6061a31880c1ed6b6ce341215336e2f3d0c1deccd84957b6fa8ca474b41e89f" "sha256:f6061a31880c1ed6b6ce341215336e2f3d0c1deccd84957b6fa8ca474b41e89f"
], ],
"markers": "python_version < '3.10' and platform_python_implementation == 'CPython'", "markers": "platform_python_implementation == 'CPython' and python_version < '3.10'",
"version": "==0.2.2" "version": "==0.2.2"
}, },
"s3transfer": { "s3transfer": {
@ -1152,7 +1091,6 @@
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0" "version": "==1.16.0"
}, },
"sqlparse": { "sqlparse": {
@ -1160,7 +1098,6 @@
"sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0", "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0",
"sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8" "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"
], ],
"markers": "python_version >= '3.5'",
"version": "==0.4.1" "version": "==0.4.1"
}, },
"structlog": { "structlog": {
@ -1216,7 +1153,6 @@
"sha256:7d6f89745680233f1c4db9ddb748df5e88d2a7a37962be174c0fd04c8dba1dc8", "sha256:7d6f89745680233f1c4db9ddb748df5e88d2a7a37962be174c0fd04c8dba1dc8",
"sha256:c16b55f9a67b2419cfdf8846576e2ec9ba94fe6978a83080c352a80db31c93fb" "sha256:c16b55f9a67b2419cfdf8846576e2ec9ba94fe6978a83080c352a80db31c93fb"
], ],
"markers": "python_version >= '3.6'",
"version": "==21.2.1" "version": "==21.2.1"
}, },
"typing-extensions": { "typing-extensions": {
@ -1232,7 +1168,6 @@
"sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f", "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f",
"sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae" "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==3.0.1" "version": "==3.0.1"
}, },
"urllib3": { "urllib3": {
@ -1277,7 +1212,6 @@
"sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30",
"sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"
], ],
"markers": "python_version >= '3.6'",
"version": "==5.0.0" "version": "==5.0.0"
}, },
"watchgod": { "watchgod": {
@ -1307,7 +1241,6 @@
"sha256:2e50d26ca593f70aba7b13a489435ef88b8fc3b5c5643c1ce8808ff9b40f0b32", "sha256:2e50d26ca593f70aba7b13a489435ef88b8fc3b5c5643c1ce8808ff9b40f0b32",
"sha256:d376bd60eace9d437ab6d7ee16f4ab4e821c9dae591e1b783c58ebd8aaf80c5c" "sha256:d376bd60eace9d437ab6d7ee16f4ab4e821c9dae591e1b783c58ebd8aaf80c5c"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.59.0" "version": "==0.59.0"
}, },
"websockets": { "websockets": {
@ -1394,7 +1327,6 @@
"sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a",
"sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71"
], ],
"markers": "python_version >= '3.6'",
"version": "==1.6.3" "version": "==1.6.3"
}, },
"zope.interface": { "zope.interface": {
@ -1451,7 +1383,6 @@
"sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4",
"sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==5.4.0" "version": "==5.4.0"
} }
}, },
@ -1468,7 +1399,6 @@
"sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e", "sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e",
"sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975" "sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975"
], ],
"markers": "python_version ~= '3.6'",
"version": "==2.5.6" "version": "==2.5.6"
}, },
"attrs": { "attrs": {
@ -1476,7 +1406,6 @@
"sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1",
"sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==21.2.0" "version": "==21.2.0"
}, },
"bandit": { "bandit": {
@ -1515,7 +1444,6 @@
"sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa",
"sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==4.0.0" "version": "==4.0.0"
}, },
"click": { "click": {
@ -1523,7 +1451,6 @@
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==7.1.2" "version": "==7.1.2"
}, },
"colorama": { "colorama": {
@ -1597,16 +1524,14 @@
"sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0",
"sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005" "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"
], ],
"markers": "python_version >= '3.4'",
"version": "==4.0.7" "version": "==4.0.7"
}, },
"gitpython": { "gitpython": {
"hashes": [ "hashes": [
"sha256:2bfcd25e6b81fe431fa3ab1f0975986cfddabf7870a323c183f3afbc9447c0c5", "sha256:29fe82050709760081f588dd50ce83504feddbebdc4da6956d02351552b1c135",
"sha256:37ac36cacf2e2be5e88f0810187c5833e71c1a2a8cf81588f5699d1b70183baa" "sha256:ee24bdc93dce357630764db659edaf6b8d664d4ff5447ccfeedd2dc5c253f41e"
], ],
"markers": "python_version >= '3.5'", "version": "==3.1.17"
"version": "==3.1.16"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
@ -1627,7 +1552,6 @@
"sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6", "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6",
"sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d" "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"
], ],
"markers": "python_version >= '3.6' and python_version < '4.0'",
"version": "==5.8.0" "version": "==5.8.0"
}, },
"lazy-object-proxy": { "lazy-object-proxy": {
@ -1655,7 +1579,6 @@
"sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93", "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93",
"sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b" "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.6.0" "version": "==1.6.0"
}, },
"mccabe": { "mccabe": {
@ -1692,7 +1615,6 @@
"sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd", "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd",
"sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4" "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"
], ],
"markers": "python_version >= '2.6'",
"version": "==5.6.0" "version": "==5.6.0"
}, },
"pluggy": { "pluggy": {
@ -1700,7 +1622,6 @@
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.13.1" "version": "==0.13.1"
}, },
"py": { "py": {
@ -1708,7 +1629,6 @@
"sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3",
"sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.10.0" "version": "==1.10.0"
}, },
"pylint": { "pylint": {
@ -1739,7 +1659,6 @@
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7" "version": "==2.4.7"
}, },
"pytest": { "pytest": {
@ -1752,11 +1671,11 @@
}, },
"pytest-django": { "pytest-django": {
"hashes": [ "hashes": [
"sha256:80f8875226ec4dc0b205f0578072034563879d98d9b1bec143a80b9045716cb0", "sha256:d1c6758a592fb0ef8abaa2fe12dd28858c1dcfc3d466102ffe52aa8934733dca",
"sha256:a51150d8962200250e850c6adcab670779b9c2aa07271471059d1fb92a843fa9" "sha256:f96c4556f4e7b15d987dd1dcc1d1526df81d40c1548d31ce840d597ed2be8c46"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.2.0" "version": "==4.3.0"
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
@ -1844,7 +1763,6 @@
"sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
"sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.25.1" "version": "==2.25.1"
}, },
"requests-mock": { "requests-mock": {
@ -1868,7 +1786,6 @@
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0" "version": "==1.16.0"
}, },
"smmap": { "smmap": {
@ -1876,7 +1793,6 @@
"sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182", "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182",
"sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2" "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"
], ],
"markers": "python_version >= '3.5'",
"version": "==4.0.0" "version": "==4.0.0"
}, },
"stevedore": { "stevedore": {
@ -1884,7 +1800,6 @@
"sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee", "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee",
"sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a" "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a"
], ],
"markers": "python_version >= '3.6'",
"version": "==3.3.0" "version": "==3.3.0"
}, },
"toml": { "toml": {
@ -1892,7 +1807,6 @@
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.2" "version": "==0.10.2"
}, },
"urllib3": { "urllib3": {

View File

@ -1,3 +1,3 @@
"""authentik""" """authentik"""
__version__ = "2021.5.1" __version__ = "2021.5.4"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -42,7 +42,7 @@ def token_from_header(raw_header: bytes) -> Optional[Token]:
return tokens.first() return tokens.first()
class AuthentikTokenAuthentication(BaseAuthentication): class TokenAuthentication(BaseAuthentication):
"""Token-based authentication using HTTP Bearer authentication""" """Token-based authentication using HTTP Bearer authentication"""
def authenticate(self, request: Request) -> Union[tuple[User, Any], None]: def authenticate(self, request: Request) -> Union[tuple[User, Any], None]:

View File

@ -0,0 +1,35 @@
"""API Authorization"""
from django.db.models import Model
from django.db.models.query import QuerySet
from rest_framework.filters import BaseFilterBackend
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
class OwnerFilter(BaseFilterBackend):
"""Filter objects by their owner"""
owner_key = "user"
def filter_queryset(self, request: Request, queryset: QuerySet, view) -> QuerySet:
return queryset.filter(**{self.owner_key: request.user})
class OwnerPermissions(BasePermission):
"""Authorize requests by an object's owner matching the requesting user"""
owner_key = "user"
def has_permission(self, request: Request, view) -> bool:
"""If the user is authenticated, we allow all requests here. For listing, the
object-level permissions are done by the filter backend"""
return request.user.is_authenticated
def has_object_permission(self, request: Request, view, obj: Model) -> bool:
"""Check if the object's owner matches the currently logged in user"""
if not hasattr(obj, self.owner_key):
return False
owner = getattr(obj, self.owner_key)
if owner != request.user:
return False
return True

View File

@ -5,7 +5,7 @@ from django.test import TestCase
from guardian.shortcuts import get_anonymous_user from guardian.shortcuts import get_anonymous_user
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
from authentik.api.auth import token_from_header from authentik.api.authentication import token_from_header
from authentik.core.models import Token, TokenIntents from authentik.core.models import Token, TokenIntents

View File

@ -169,9 +169,19 @@ router.register("propertymappings/scope", ScopeMappingViewSet)
router.register("authenticators/static", StaticDeviceViewSet) router.register("authenticators/static", StaticDeviceViewSet)
router.register("authenticators/totp", TOTPDeviceViewSet) router.register("authenticators/totp", TOTPDeviceViewSet)
router.register("authenticators/webauthn", WebAuthnDeviceViewSet) router.register("authenticators/webauthn", WebAuthnDeviceViewSet)
router.register("authenticators/admin/static", StaticAdminDeviceViewSet) router.register(
router.register("authenticators/admin/totp", TOTPAdminDeviceViewSet) "authenticators/admin/static",
router.register("authenticators/admin/webauthn", WebAuthnAdminDeviceViewSet) StaticAdminDeviceViewSet,
basename="admin-staticdevice",
)
router.register(
"authenticators/admin/totp", TOTPAdminDeviceViewSet, basename="admin-totpdevice"
)
router.register(
"authenticators/admin/webauthn",
WebAuthnAdminDeviceViewSet,
basename="admin-webauthndevice",
)
router.register("stages/all", StageViewSet) router.register("stages/all", StageViewSet)
router.register("stages/authenticator/static", AuthenticatorStaticStageViewSet) router.register("stages/authenticator/static", AuthenticatorStaticStageViewSet)

View File

@ -23,6 +23,7 @@ from authentik.core.api.providers import ProviderSerializer
from authentik.core.models import Application from authentik.core.models import Application
from authentik.events.models import EventAction from authentik.events.models import EventAction
from authentik.policies.engine import PolicyEngine from authentik.policies.engine import PolicyEngine
from authentik.stages.user_login.stage import USER_LOGIN_AUTHENTICATED
LOGGER = get_logger() LOGGER = get_logger()
@ -122,6 +123,7 @@ class ApplicationViewSet(ModelViewSet):
) )
def list(self, request: Request) -> Response: def list(self, request: Request) -> Response:
"""Custom list method that checks Policy based access instead of guardian""" """Custom list method that checks Policy based access instead of guardian"""
self.request.session.pop(USER_LOGIN_AUTHENTICATED, None)
queryset = self._filter_queryset_for_list(self.get_queryset()) queryset = self._filter_queryset_for_list(self.get_queryset())
self.paginate_queryset(queryset) self.paginate_queryset(queryset)

View File

@ -78,7 +78,7 @@ class PropertyMappingViewSet(
filterset_fields = {"managed": ["isnull"]} filterset_fields = {"managed": ["isnull"]}
ordering = ["name"] ordering = ["name"]
def get_queryset(self): def get_queryset(self): # pragma: no cover
return PropertyMapping.objects.select_subclasses() return PropertyMapping.objects.select_subclasses()
@swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)})

View File

@ -63,7 +63,7 @@ class ProviderViewSet(
"application__name", "application__name",
] ]
def get_queryset(self): def get_queryset(self): # pragma: no cover
return Provider.objects.select_subclasses() return Provider.objects.select_subclasses()
@swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)})

View File

@ -61,7 +61,7 @@ class SourceViewSet(
serializer_class = SourceSerializer serializer_class = SourceSerializer
lookup_field = "slug" lookup_field = "slug"
def get_queryset(self): def get_queryset(self): # pragma: no cover
return Source.objects.select_subclasses() return Source.objects.select_subclasses()
@swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)})

View File

@ -139,7 +139,7 @@ class UserViewSet(ModelViewSet):
search_fields = ["username", "name", "is_active"] search_fields = ["username", "name", "is_active"]
filterset_class = UsersFilter filterset_class = UsersFilter
def get_queryset(self): def get_queryset(self): # pragma: no cover
return User.objects.all().exclude(pk=get_anonymous_user().pk) return User.objects.all().exclude(pk=get_anonymous_user().pk)
@swagger_auto_schema(responses={200: SessionUserSerializer(many=False)}) @swagger_auto_schema(responses={200: SessionUserSerializer(many=False)})

View File

@ -4,7 +4,7 @@ from channels.generic.websocket import JsonWebsocketConsumer
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.api.auth import token_from_header from authentik.api.authentication import token_from_header
from authentik.core.models import User from authentik.core.models import User
LOGGER = get_logger() LOGGER = get_logger()

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.3 on 2021-05-14 08:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0020_source_user_matching_mode"),
]
operations = [
migrations.AlterField(
model_name="application",
name="slug",
field=models.SlugField(
help_text="Internal application name, used in URLs.", unique=True
),
),
]

View File

@ -207,7 +207,9 @@ class Application(PolicyBindingModel):
add custom fields and other properties""" add custom fields and other properties"""
name = models.TextField(help_text=_("Application's display Name.")) name = models.TextField(help_text=_("Application's display Name."))
slug = models.SlugField(help_text=_("Internal application name, used in URLs.")) slug = models.SlugField(
help_text=_("Internal application name, used in URLs."), unique=True
)
provider = models.OneToOneField( provider = models.OneToOneField(
"Provider", null=True, blank=True, default=None, on_delete=models.SET_DEFAULT "Provider", null=True, blank=True, default=None, on_delete=models.SET_DEFAULT
) )

View File

@ -1,12 +1,12 @@
"""Notification API Views""" """Notification API Views"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from guardian.utils import get_anonymous_user
from rest_framework import mixins from rest_framework import mixins
from rest_framework.fields import ReadOnlyField from rest_framework.fields import ReadOnlyField
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import GenericViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.events.api.event import EventSerializer from authentik.events.api.event import EventSerializer
from authentik.events.models import Notification from authentik.events.models import Notification
@ -49,12 +49,5 @@ class NotificationViewSet(
"event", "event",
"seen", "seen",
] ]
filter_backends = [ permission_classes = [OwnerPermissions]
DjangoFilterBackend, filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
OrderingFilter,
SearchFilter,
]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()
return Notification.objects.filter(user=user.pk)

View File

@ -65,7 +65,7 @@ class StageViewSet(
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]
def get_queryset(self): def get_queryset(self): # pragma: no cover
return Stage.objects.select_subclasses() return Stage.objects.select_subclasses()
@swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)})

View File

@ -21,7 +21,7 @@ context["user_backend"] = "django.contrib.auth.backends.ModelBackend"
return True""" return True"""
def create_default_oob_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): def create_default_oobe_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.stages.prompt.models import FieldTypes from authentik.stages.prompt.models import FieldTypes
User = apps.get_model("authentik_core", "User") User = apps.get_model("authentik_core", "User")
@ -52,20 +52,20 @@ def create_default_oob_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor)
# Create a policy that sets the flow's user # Create a policy that sets the flow's user
prefill_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create( prefill_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create(
name="default-oob-prefill-user", name="default-oobe-prefill-user",
defaults={"expression": PREFILL_POLICY_EXPRESSION}, defaults={"expression": PREFILL_POLICY_EXPRESSION},
) )
password_usable_policy, _ = ExpressionPolicy.objects.using( password_usable_policy, _ = ExpressionPolicy.objects.using(
db_alias db_alias
).update_or_create( ).update_or_create(
name="default-oob-password-usable", name="default-oobe-password-usable",
defaults={"expression": PW_USABLE_POLICY_EXPRESSION}, defaults={"expression": PW_USABLE_POLICY_EXPRESSION},
) )
prompt_header, _ = Prompt.objects.using(db_alias).update_or_create( prompt_header, _ = Prompt.objects.using(db_alias).update_or_create(
field_key="oob-header-text", field_key="oobe-header-text",
defaults={ defaults={
"label": "oob-header-text", "label": "oobe-header-text",
"type": FieldTypes.STATIC, "type": FieldTypes.STATIC,
"placeholder": "Welcome to authentik! Please set a password for the default admin user, akadmin.", "placeholder": "Welcome to authentik! Please set a password for the default admin user, akadmin.",
"order": 100, "order": 100,
@ -84,7 +84,7 @@ def create_default_oob_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor)
password_second = Prompt.objects.using(db_alias).get(field_key="password_repeat") password_second = Prompt.objects.using(db_alias).get(field_key="password_repeat")
prompt_stage, _ = PromptStage.objects.using(db_alias).update_or_create( prompt_stage, _ = PromptStage.objects.using(db_alias).update_or_create(
name="default-oob-password", name="default-oobe-password",
) )
prompt_stage.fields.set( prompt_stage.fields.set(
[prompt_header, prompt_email, password_first, password_second] [prompt_header, prompt_email, password_first, password_second]
@ -102,7 +102,7 @@ def create_default_oob_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor)
slug="initial-setup", slug="initial-setup",
designation=FlowDesignation.STAGE_CONFIGURATION, designation=FlowDesignation.STAGE_CONFIGURATION,
defaults={ defaults={
"name": "default-oob-setup", "name": "default-oobe-setup",
"title": "Welcome to authentik!", "title": "Welcome to authentik!",
}, },
) )
@ -146,5 +146,5 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(create_default_oob_flow), migrations.RunPython(create_default_oobe_flow),
] ]

View File

@ -298,7 +298,7 @@ class CancelView(View):
if SESSION_KEY_PLAN in request.session: if SESSION_KEY_PLAN in request.session:
del request.session[SESSION_KEY_PLAN] del request.session[SESSION_KEY_PLAN]
LOGGER.debug("Canceled current plan") LOGGER.debug("Canceled current plan")
return redirect("authentik_core:default-invalidation") return redirect("authentik_flows:default-invalidation")
class ToDefaultFlow(View): class ToDefaultFlow(View):

View File

@ -88,10 +88,10 @@ class ConfigLoader:
value = os.getenv(url.netloc, url.query) value = os.getenv(url.netloc, url.query)
if url.scheme == "file": if url.scheme == "file":
try: try:
with open(url.netloc, "r") as _file: with open(url.path, "r") as _file:
value = _file.read() value = _file.read()
except OSError: except OSError:
self._log("error", f"Failed to read config value from {url.netloc}") self._log("error", f"Failed to read config value from {url.path}")
value = url.query value = url.query
return value return value

View File

@ -8,7 +8,11 @@ from botocore.exceptions import BotoCoreError
from celery.exceptions import CeleryError from celery.exceptions import CeleryError
from channels.middleware import BaseMiddleware from channels.middleware import BaseMiddleware
from channels_redis.core import ChannelFull from channels_redis.core import ChannelFull
from django.core.exceptions import SuspiciousOperation, ValidationError from django.core.exceptions import (
ImproperlyConfigured,
SuspiciousOperation,
ValidationError,
)
from django.db import InternalError, OperationalError, ProgrammingError from django.db import InternalError, OperationalError, ProgrammingError
from django.http.response import Http404 from django.http.response import Http404
from django_redis.exceptions import ConnectionInterrupted from django_redis.exceptions import ConnectionInterrupted
@ -51,7 +55,8 @@ def before_send(event: dict, hint: dict) -> Optional[dict]:
ConnectionResetError, ConnectionResetError,
OSError, OSError,
PermissionError, PermissionError,
# Django DB Errors # Django Errors
ImproperlyConfigured,
OperationalError, OperationalError,
InternalError, InternalError,
ProgrammingError, ProgrammingError,

View File

@ -17,7 +17,8 @@ def _get_client_ip_from_meta(meta: dict[str, Any]) -> Optional[str]:
) )
for _header in headers: for _header in headers:
if _header in meta: if _header in meta:
return meta.get(_header).split(", ")[0] ips: list[str] = meta.get(_header).split(",")
return ips[0].strip()
return None return None

View File

@ -2,28 +2,6 @@
from django.http import HttpRequest from django.http import HttpRequest
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView
from guardian.shortcuts import assign_perm
class CreateAssignPermView(CreateView):
"""Assign permissions to object after creation"""
permissions = [
"%s.view_%s",
"%s.change_%s",
"%s.delete_%s",
]
def form_valid(self, form):
response = super().form_valid(form)
for permission in self.permissions:
full_permission = permission % (
self.object._meta.app_label,
self.object._meta.model_name,
)
assign_perm(full_permission, self.request.user, self.object)
return response
def bad_request_message( def bad_request_message(

View File

@ -40,7 +40,7 @@ class WebsocketMessage:
class OutpostConsumer(AuthJsonConsumer): class OutpostConsumer(AuthJsonConsumer):
"""Handler for Outposts that connect over websockets for health checks and live updates""" """Handler for Outposts that connect over websockets for health checks and live updates"""
outpost: Optional[Outpost] = None outpost: Outpost
last_uid: Optional[str] = None last_uid: Optional[str] = None
@ -64,7 +64,10 @@ class OutpostConsumer(AuthJsonConsumer):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def disconnect(self, close_code): def disconnect(self, close_code):
if self.outpost and self.last_uid: if self.outpost and self.last_uid:
OutpostState.for_channel(self.outpost, self.last_uid).delete() state = OutpostState.for_instance_uid(self.outpost, self.last_uid)
if self.channel_name in state.channel_ids:
state.channel_ids.remove(self.channel_name)
state.save()
LOGGER.debug( LOGGER.debug(
"removed outpost instance from cache", "removed outpost instance from cache",
outpost=self.outpost, outpost=self.outpost,
@ -75,11 +78,10 @@ class OutpostConsumer(AuthJsonConsumer):
msg = from_dict(WebsocketMessage, content) msg = from_dict(WebsocketMessage, content)
uid = msg.args.get("uuid", self.channel_name) uid = msg.args.get("uuid", self.channel_name)
self.last_uid = uid self.last_uid = uid
state = OutpostState( state = OutpostState.for_instance_uid(self.outpost, uid)
uid=uid, if self.channel_name not in state.channel_ids:
last_seen=datetime.now(), state.channel_ids.append(self.channel_name)
_outpost=self.outpost, state.last_seen = datetime.now()
)
if msg.instruction == WebsocketMessageInstruction.HELLO: if msg.instruction == WebsocketMessageInstruction.HELLO:
state.version = msg.args.get("version", None) state.version = msg.args.get("version", None)
state.build_hash = msg.args.get("buildHash", "") state.build_hash = msg.args.get("buildHash", "")

View File

@ -409,6 +409,7 @@ class OutpostState:
"""Outpost instance state, last_seen and version""" """Outpost instance state, last_seen and version"""
uid: str uid: str
channel_ids: list[str] = field(default_factory=list)
last_seen: Optional[datetime] = field(default=None) last_seen: Optional[datetime] = field(default=None)
version: Optional[str] = field(default=None) version: Optional[str] = field(default=None)
version_should: Union[Version, LegacyVersion] = field(default=OUR_VERSION) version_should: Union[Version, LegacyVersion] = field(default=OUR_VERSION)
@ -431,21 +432,20 @@ class OutpostState:
keys = cache.keys(f"{outpost.state_cache_prefix}_*") keys = cache.keys(f"{outpost.state_cache_prefix}_*")
states = [] states = []
for key in keys: for key in keys:
channel = key.replace(f"{outpost.state_cache_prefix}_", "") instance_uid = key.replace(f"{outpost.state_cache_prefix}_", "")
states.append(OutpostState.for_channel(outpost, channel)) states.append(OutpostState.for_instance_uid(outpost, instance_uid))
return states return states
@staticmethod @staticmethod
def for_channel(outpost: Outpost, channel: str) -> "OutpostState": def for_instance_uid(outpost: Outpost, uid: str) -> "OutpostState":
"""Get state for a single channel""" """Get state for a single instance"""
key = f"{outpost.state_cache_prefix}_{channel}" key = f"{outpost.state_cache_prefix}_{uid}"
default_data = {"uid": channel} default_data = {"uid": uid, "channel_ids": []}
data = cache.get(key, default_data) data = cache.get(key, default_data)
if isinstance(data, str): if isinstance(data, str):
cache.delete(key) cache.delete(key)
data = default_data data = default_data
state = from_dict(OutpostState, data) state = from_dict(OutpostState, data)
state.uid = channel
# pylint: disable=protected-access # pylint: disable=protected-access
state._outpost = outpost state._outpost = outpost
return state return state

View File

@ -100,6 +100,8 @@ def outpost_controller(
outpost: Outpost = cache.get(CACHE_KEY_OUTPOST_DOWN % outpost_pk) outpost: Outpost = cache.get(CACHE_KEY_OUTPOST_DOWN % outpost_pk)
else: else:
outpost: Outpost = Outpost.objects.get(pk=outpost_pk) outpost: Outpost = Outpost.objects.get(pk=outpost_pk)
if not outpost:
return
self.set_uid(slugify(outpost.name)) self.set_uid(slugify(outpost.name))
try: try:
controller = controller_for_outpost(outpost) controller = controller_for_outpost(outpost)
@ -200,8 +202,11 @@ def _outpost_single_update(outpost: Outpost, layer=None):
if not layer: # pragma: no cover if not layer: # pragma: no cover
layer = get_channel_layer() layer = get_channel_layer()
for state in OutpostState.for_outpost(outpost): for state in OutpostState.for_outpost(outpost):
LOGGER.debug("sending update", channel=state.uid, outpost=outpost) for channel in state.channel_ids:
async_to_sync(layer.send)(state.uid, {"type": "event.update"}) LOGGER.debug(
"sending update", channel=channel, instance=state.uid, outpost=outpost
)
async_to_sync(layer.send)(channel, {"type": "event.update"})
@CELERY_APP.task() @CELERY_APP.task()

View File

@ -91,7 +91,7 @@ class PolicyViewSet(
} }
search_fields = ["name"] search_fields = ["name"]
def get_queryset(self): def get_queryset(self): # pragma: no cover
return Policy.objects.select_subclasses().prefetch_related( return Policy.objects.select_subclasses().prefetch_related(
"bindings", "promptstage_set" "bindings", "promptstage_set"
) )

View File

@ -105,16 +105,21 @@ class PolicyEngine:
if cached_policy and self.use_cache: if cached_policy and self.use_cache:
self.logger.debug( self.logger.debug(
"P_ENG: Taking result from cache", "P_ENG: Taking result from cache",
policy=binding.policy, binding=binding,
cache_key=key, cache_key=key,
request=self.request,
) )
self.__cached_policies.append(cached_policy) self.__cached_policies.append(cached_policy)
continue continue
self.logger.debug("P_ENG: Evaluating policy", policy=binding.policy) self.logger.debug(
"P_ENG: Evaluating policy", binding=binding, request=self.request
)
our_end, task_end = Pipe(False) our_end, task_end = Pipe(False)
task = PolicyProcess(binding, self.request, task_end) task = PolicyProcess(binding, self.request, task_end)
task.daemon = False task.daemon = False
self.logger.debug("P_ENG: Starting Process", policy=binding.policy) self.logger.debug(
"P_ENG: Starting Process", binding=binding, request=self.request
)
if not CURRENT_PROCESS._config.get("daemon"): if not CURRENT_PROCESS._config.get("daemon"):
task.run() task.run()
else: else:

View File

@ -51,7 +51,12 @@ class PolicyRequest:
LOGGER.warning("failed to get geoip data", exc=exc) LOGGER.warning("failed to get geoip data", exc=exc)
def __str__(self): def __str__(self):
return f"<PolicyRequest user={self.user}>" text = f"<PolicyRequest user={self.user}"
if self.obj:
text += f" obj={self.obj}"
if self.http_request:
text += f" http_request={self.http_request}"
return text + ">"
@dataclass @dataclass

View File

@ -6,13 +6,11 @@ import time
from dataclasses import asdict, dataclass, field from dataclasses import asdict, dataclass, field
from datetime import datetime from datetime import datetime
from hashlib import sha256 from hashlib import sha256
from typing import Any, Optional, Type, Union from typing import Any, Optional, Type
from urllib.parse import urlparse from urllib.parse import urlparse
from uuid import uuid4 from uuid import uuid4
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from dacite import from_dict from dacite import from_dict
from django.conf import settings
from django.db import models from django.db import models
from django.http import HttpRequest from django.http import HttpRequest
from django.utils import dateformat, timezone from django.utils import dateformat, timezone
@ -239,7 +237,7 @@ class OAuth2Provider(Provider):
token.access_token = token.create_access_token(user, request) token.access_token = token.create_access_token(user, request)
return token return token
def get_jwt_keys(self) -> Union[RSAPrivateKey, str]: def get_jwt_key(self) -> str:
""" """
Takes a provider and returns the set of keys associated with it. Takes a provider and returns the set of keys associated with it.
Returns a list of keys. Returns a list of keys.
@ -256,7 +254,7 @@ class OAuth2Provider(Provider):
self.jwt_alg = JWTAlgorithms.HS256 self.jwt_alg = JWTAlgorithms.HS256
self.save() self.save()
else: else:
return self.rsa_key.private_key return self.rsa_key.key_data
if self.jwt_alg == JWTAlgorithms.HS256: if self.jwt_alg == JWTAlgorithms.HS256:
return self.client_secret return self.client_secret
@ -300,11 +298,14 @@ class OAuth2Provider(Provider):
def encode(self, payload: dict[str, Any]) -> str: def encode(self, payload: dict[str, Any]) -> str:
"""Represent the ID Token as a JSON Web Token (JWT).""" """Represent the ID Token as a JSON Web Token (JWT)."""
key = self.get_jwt_keys() headers = {}
if self.rsa_key:
headers["kid"] = self.rsa_key.kid
key = self.get_jwt_key()
# If the provider does not have an RSA Key assigned, it was switched to Symmetric # If the provider does not have an RSA Key assigned, it was switched to Symmetric
self.refresh_from_db() self.refresh_from_db()
# pyright: reportGeneralTypeIssues=false # pyright: reportGeneralTypeIssues=false
return encode(payload, key, algorithm=self.jwt_alg) return encode(payload, key, algorithm=self.jwt_alg, headers=headers)
class Meta: class Meta:
@ -457,7 +458,7 @@ class RefreshToken(ExpiringModel, BaseGrantModel):
See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken""" See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken"""
sub = "" sub = ""
if self.provider.sub_mode == SubModes.HASHED_USER_ID: if self.provider.sub_mode == SubModes.HASHED_USER_ID:
sub = sha256(f"{user.id}-{settings.SECRET_KEY}".encode("ascii")).hexdigest() sub = user.uid
elif self.provider.sub_mode == SubModes.USER_EMAIL: elif self.provider.sub_mode == SubModes.USER_EMAIL:
sub = user.email sub = user.email
elif self.provider.sub_mode == SubModes.USER_USERNAME: elif self.provider.sub_mode == SubModes.USER_USERNAME:

View File

@ -4,6 +4,7 @@ from django.urls import reverse
from django.utils.encoding import force_str from django.utils.encoding import force_str
from authentik.core.models import Application, User from authentik.core.models import Application, User
from authentik.crypto.models import CertificateKeyPair
from authentik.flows.challenge import ChallengeTypes from authentik.flows.challenge import ChallengeTypes
from authentik.flows.models import Flow from authentik.flows.models import Flow
from authentik.providers.oauth2.errors import ( from authentik.providers.oauth2.errors import (
@ -207,6 +208,7 @@ class TestAuthorize(OAuthTestCase):
client_secret=generate_client_secret(), client_secret=generate_client_secret(),
authorization_flow=flow, authorization_flow=flow,
redirect_uris="http://localhost", redirect_uris="http://localhost",
rsa_key=CertificateKeyPair.objects.first(),
) )
Application.objects.create(name="app", slug="app", provider=provider) Application.objects.create(name="app", slug="app", provider=provider)
state = generate_client_id() state = generate_client_id()

View File

@ -2,7 +2,11 @@
from django.test import TestCase from django.test import TestCase
from jwt import decode from jwt import decode
from authentik.providers.oauth2.models import OAuth2Provider, RefreshToken from authentik.providers.oauth2.models import (
JWTAlgorithms,
OAuth2Provider,
RefreshToken,
)
class OAuthTestCase(TestCase): class OAuthTestCase(TestCase):
@ -19,9 +23,12 @@ class OAuthTestCase(TestCase):
def validate_jwt(self, token: RefreshToken, provider: OAuth2Provider): def validate_jwt(self, token: RefreshToken, provider: OAuth2Provider):
"""Validate that all required fields are set""" """Validate that all required fields are set"""
key = provider.client_secret
if provider.jwt_alg == JWTAlgorithms.RS256:
key = provider.rsa_key.public_key
jwt = decode( jwt = decode(
token.access_token, token.access_token,
provider.client_secret, key,
algorithms=[provider.jwt_alg], algorithms=[provider.jwt_alg],
audience=provider.client_id, audience=provider.client_id,
) )

View File

@ -54,6 +54,7 @@ from authentik.stages.consent.stage import (
PLAN_CONTEXT_CONSENT_PERMISSIONS, PLAN_CONTEXT_CONSENT_PERMISSIONS,
ConsentStageView, ConsentStageView,
) )
from authentik.stages.user_login.stage import USER_LOGIN_AUTHENTICATED
LOGGER = get_logger() LOGGER = get_logger()
@ -437,6 +438,10 @@ class AuthorizationFlowInitView(PolicyAccessView):
if ( if (
PROMPT_LOGIN in self.params.prompt PROMPT_LOGIN in self.params.prompt
and SESSION_NEEDS_LOGIN not in self.request.session and SESSION_NEEDS_LOGIN not in self.request.session
# To prevent the user from having to double login when prompt is set to login
# and the user has just signed it. This session variable is set in the UserLoginStage
# and is (quite hackily) removed from the session in applications's API's List method
and USER_LOGIN_AUTHENTICATED not in self.request.session
): ):
self.request.session[SESSION_NEEDS_LOGIN] = True self.request.session[SESSION_NEEDS_LOGIN] = True
return self.handle_no_permission() return self.handle_no_permission()

View File

@ -53,8 +53,10 @@ class ProxyProviderSerializer(ProviderSerializer):
return instance return instance
def update(self, instance: ProxyProvider, validated_data): def update(self, instance: ProxyProvider, validated_data):
instance = super().update(instance, validated_data)
instance.set_oauth_defaults() instance.set_oauth_defaults()
return super().update(instance, validated_data) instance.save()
return instance
class Meta: class Meta:

View File

@ -127,7 +127,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
"""Ensure all OAuth2-related settings are correct""" """Ensure all OAuth2-related settings are correct"""
self.client_type = ClientTypes.CONFIDENTIAL self.client_type = ClientTypes.CONFIDENTIAL
self.jwt_alg = JWTAlgorithms.RS256 self.jwt_alg = JWTAlgorithms.RS256
self.rsa_key = CertificateKeyPair.objects.first() self.rsa_key = CertificateKeyPair.objects.exclude(key_data__iexact="").first()
scopes = ScopeMapping.objects.filter( scopes = ScopeMapping.objects.filter(
scope_name__in=[ scope_name__in=[
SCOPE_OPENID, SCOPE_OPENID,

View File

@ -20,6 +20,7 @@ from time import time
import structlog import structlog
from celery.schedules import crontab from celery.schedules import crontab
from sentry_sdk import init as sentry_init from sentry_sdk import init as sentry_init
from sentry_sdk.api import set_tag
from sentry_sdk.integrations.celery import CeleryIntegration from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.redis import RedisIntegration from sentry_sdk.integrations.redis import RedisIntegration
@ -52,11 +53,9 @@ STATIC_ROOT = BASE_DIR + "/static"
STATICFILES_DIRS = [BASE_DIR + "/web"] STATICFILES_DIRS = [BASE_DIR + "/web"]
MEDIA_ROOT = BASE_DIR + "/media" MEDIA_ROOT = BASE_DIR + "/media"
SECRET_KEY = CONFIG.y(
"secret_key", "9$@r!d^1^jrn#fk#1#@ks#9&i$^s#1)_13%$rwjrhd=e8jfi_s"
) # noqa Debug
DEBUG = CONFIG.y_bool("debug") DEBUG = CONFIG.y_bool("debug")
SECRET_KEY = CONFIG.y("secret_key")
INTERNAL_IPS = ["127.0.0.1"] INTERNAL_IPS = ["127.0.0.1"]
ALLOWED_HOSTS = ["*"] ALLOWED_HOSTS = ["*"]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
@ -162,7 +161,7 @@ REST_FRAMEWORK = {
"rest_framework.permissions.DjangoObjectPermissions", "rest_framework.permissions.DjangoObjectPermissions",
), ),
"DEFAULT_AUTHENTICATION_CLASSES": ( "DEFAULT_AUTHENTICATION_CLASSES": (
"authentik.api.auth.AuthentikTokenAuthentication", "authentik.api.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.SessionAuthentication",
), ),
"DEFAULT_RENDERER_CLASSES": [ "DEFAULT_RENDERER_CLASSES": [
@ -354,6 +353,11 @@ if _ERROR_REPORTING:
environment=CONFIG.y("error_reporting.environment", "customer"), environment=CONFIG.y("error_reporting.environment", "customer"),
send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False), send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False),
) )
set_tag("authentik:build_hash", os.environ.get(ENV_GIT_HASH_KEY, "tagged"))
set_tag(
"authentik:env", "kubernetes" if "KUBERNETES_PORT" in os.environ else "compose"
)
set_tag("authentik:component", "backend")
j_print( j_print(
"Error reporting is enabled", "Error reporting is enabled",
env=CONFIG.y("error_reporting.environment", "customer"), env=CONFIG.y("error_reporting.environment", "customer"),

View File

@ -1,9 +1,10 @@
"""OAuth Source Serializer""" """OAuth Source Serializer"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from guardian.utils import get_anonymous_user from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import GenericViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.sources import SourceSerializer from authentik.core.api.sources import SourceSerializer
from authentik.sources.oauth.models import UserOAuthSourceConnection from authentik.sources.oauth.models import UserOAuthSourceConnection
@ -21,20 +22,17 @@ class UserOAuthSourceConnectionSerializer(SourceSerializer):
] ]
class UserOAuthSourceConnectionViewSet(ModelViewSet): class UserOAuthSourceConnectionViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Source Viewset""" """Source Viewset"""
queryset = UserOAuthSourceConnection.objects.all() queryset = UserOAuthSourceConnection.objects.all()
serializer_class = UserOAuthSourceConnectionSerializer serializer_class = UserOAuthSourceConnectionSerializer
filterset_fields = ["source__slug"] filterset_fields = ["source__slug"]
filter_backends = [ permission_classes = [OwnerPermissions]
DjangoFilterBackend, filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
OrderingFilter,
SearchFilter,
]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()
if user.is_superuser:
return super().get_queryset()
return super().get_queryset().filter(user=user.pk)

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.3 on 2021-05-20 17:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_plex", "0002_auto_20210505_1717"),
]
operations = [
migrations.AlterField(
model_name="plexsource",
name="plex_token",
field=models.TextField(help_text="Plex token used to check firends"),
),
]

View File

@ -41,9 +41,7 @@ class PlexSource(Source):
default=True, default=True,
help_text=_("Allow friends to authenticate, even if you don't share a server."), help_text=_("Allow friends to authenticate, even if you don't share a server."),
) )
plex_token = models.TextField( plex_token = models.TextField(help_text=_("Plex token used to check firends"))
default="", help_text=_("Plex token used to check firends")
)
@property @property
def component(self) -> str: def component(self) -> str:

View File

@ -1,12 +1,13 @@
"""AuthenticatorStaticStage API Views""" """AuthenticatorStaticStage API Views"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from django_otp.plugins.otp_static.models import StaticDevice from django_otp.plugins.otp_static.models import StaticDevice
from guardian.utils import get_anonymous_user from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.flows.api.stages import StageSerializer from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_static.models import AuthenticatorStaticStage from authentik.stages.authenticator_static.models import AuthenticatorStaticStage
@ -37,23 +38,22 @@ class StaticDeviceSerializer(ModelSerializer):
depth = 2 depth = 2
class StaticDeviceViewSet(ModelViewSet): class StaticDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Viewset for static authenticator devices""" """Viewset for static authenticator devices"""
queryset = StaticDevice.objects.none() queryset = StaticDevice.objects.all()
serializer_class = StaticDeviceSerializer serializer_class = StaticDeviceSerializer
permission_classes = [OwnerPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]
ordering = ["name"] ordering = ["name"]
filter_backends = [
DjangoFilterBackend,
OrderingFilter,
SearchFilter,
]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()
return StaticDevice.objects.filter(user=user.pk)
class StaticAdminDeviceViewSet(ReadOnlyModelViewSet): class StaticAdminDeviceViewSet(ReadOnlyModelViewSet):

View File

@ -0,0 +1,20 @@
"""Test Static API"""
from django.urls import reverse
from django_otp.plugins.otp_static.models import StaticDevice
from rest_framework.test import APITestCase
from authentik.core.models import User
class AuthenticatorStaticStage(APITestCase):
"""Test Static API"""
def test_api_delete(self):
"""Test api delete"""
user = User.objects.create(username="foo")
self.client.force_login(user)
dev = StaticDevice.objects.create(user=user)
response = self.client.delete(
reverse("authentik_api:staticdevice-detail", kwargs={"pk": dev.pk})
)
self.assertEqual(response.status_code, 204)

View File

@ -1,12 +1,13 @@
"""AuthenticatorTOTPStage API Views""" """AuthenticatorTOTPStage API Views"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework.backends import DjangoFilterBackend
from django_otp.plugins.otp_totp.models import TOTPDevice from django_otp.plugins.otp_totp.models import TOTPDevice
from guardian.utils import get_anonymous_user from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.flows.api.stages import StageSerializer from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage
@ -40,23 +41,22 @@ class TOTPDeviceSerializer(ModelSerializer):
depth = 2 depth = 2
class TOTPDeviceViewSet(ModelViewSet): class TOTPDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Viewset for totp authenticator devices""" """Viewset for totp authenticator devices"""
queryset = TOTPDevice.objects.none() queryset = TOTPDevice.objects.all()
serializer_class = TOTPDeviceSerializer serializer_class = TOTPDeviceSerializer
permission_classes = [OwnerPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]
ordering = ["name"] ordering = ["name"]
filter_backends = [
DjangoFilterBackend,
OrderingFilter,
SearchFilter,
]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()
return TOTPDevice.objects.filter(user=user.pk)
class TOTPAdminDeviceViewSet(ReadOnlyModelViewSet): class TOTPAdminDeviceViewSet(ReadOnlyModelViewSet):

View File

@ -0,0 +1,20 @@
"""Test TOTP API"""
from django.urls import reverse
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework.test import APITestCase
from authentik.core.models import User
class AuthenticatorTOTPStage(APITestCase):
"""Test TOTP API"""
def test_api_delete(self):
"""Test api delete"""
user = User.objects.create(username="foo")
self.client.force_login(user)
dev = TOTPDevice.objects.create(user=user)
response = self.client.delete(
reverse("authentik_api:totpdevice-detail", kwargs={"pk": dev.pk})
)
self.assertEqual(response.status_code, 204)

View File

@ -1,11 +1,12 @@
"""AuthenticateWebAuthnStage API Views""" """AuthenticateWebAuthnStage API Views"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework.backends import DjangoFilterBackend
from guardian.utils import get_anonymous_user from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.flows.api.stages import StageSerializer from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_webauthn.models import ( from authentik.stages.authenticator_webauthn.models import (
AuthenticateWebAuthnStage, AuthenticateWebAuthnStage,
@ -39,23 +40,22 @@ class WebAuthnDeviceSerializer(ModelSerializer):
depth = 2 depth = 2
class WebAuthnDeviceViewSet(ModelViewSet): class WebAuthnDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Viewset for WebAuthn authenticator devices""" """Viewset for WebAuthn authenticator devices"""
queryset = WebAuthnDevice.objects.none() queryset = WebAuthnDevice.objects.all()
serializer_class = WebAuthnDeviceSerializer serializer_class = WebAuthnDeviceSerializer
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]
ordering = ["name"] ordering = ["name"]
filter_backends = [ permission_classes = [OwnerPermissions]
DjangoFilterBackend, filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
OrderingFilter,
SearchFilter,
]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()
return WebAuthnDevice.objects.filter(user=user.pk)
class WebAuthnAdminDeviceViewSet(ReadOnlyModelViewSet): class WebAuthnAdminDeviceViewSet(ReadOnlyModelViewSet):

View File

@ -0,0 +1,20 @@
"""Test WebAuthn API"""
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import User
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
class AuthenticatorWebAuthnStage(APITestCase):
"""Test WebAuthn API"""
def test_api_delete(self):
"""Test api delete"""
user = User.objects.create(username="foo")
self.client.force_login(user)
dev = WebAuthnDevice.objects.create(user=user)
response = self.client.delete(
reverse("authentik_api:webauthndevice-detail", kwargs={"pk": dev.pk})
)
self.assertEqual(response.status_code, 204)

View File

@ -1,5 +1,5 @@
"""dummy tests""" """dummy tests"""
from django.test import Client, TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_str from django.utils.encoding import force_str
@ -14,7 +14,6 @@ class TestDummyStage(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create(username="unittest", email="test@beryju.org") self.user = User.objects.create(username="unittest", email="test@beryju.org")
self.client = Client()
self.flow = Flow.objects.create( self.flow = Flow.objects.create(
name="test-dummy", name="test-dummy",

View File

@ -12,6 +12,7 @@ from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
LOGGER = get_logger() LOGGER = get_logger()
DEFAULT_BACKEND = "django.contrib.auth.backends.ModelBackend" DEFAULT_BACKEND = "django.contrib.auth.backends.ModelBackend"
USER_LOGIN_AUTHENTICATED = "user_login_authenticated"
class UserLoginStageView(StageView): class UserLoginStageView(StageView):
@ -43,5 +44,6 @@ class UserLoginStageView(StageView):
flow_slug=self.executor.flow.slug, flow_slug=self.executor.flow.slug,
session_duration=self.executor.current_stage.session_duration, session_duration=self.executor.current_stage.session_duration,
) )
self.request.session[USER_LOGIN_AUTHENTICATED] = True
messages.success(self.request, _("Successfully logged in!")) messages.success(self.request, _("Successfully logged in!"))
return self.executor.stage_ok() return self.executor.stage_ok()

View File

@ -43,7 +43,9 @@ stages:
pipenv install --dev pipenv install --dev
- task: CmdLine@2 - task: CmdLine@2
inputs: inputs:
script: pipenv run pylint authentik tests lifecycle script: |
pipenv run python -m scripts.generate_ci_config
pipenv run pylint authentik tests lifecycle
- job: black - job: black
pool: pool:
vmImage: 'ubuntu-latest' vmImage: 'ubuntu-latest'
@ -140,7 +142,9 @@ stages:
pipenv install --dev pipenv install --dev
- task: CmdLine@2 - task: CmdLine@2
inputs: inputs:
script: pipenv run ./manage.py migrate script: |
pipenv run python -m scripts.generate_ci_config
pipenv run ./manage.py migrate
- job: migrations_from_previous_release - job: migrations_from_previous_release
pool: pool:
vmImage: 'ubuntu-latest' vmImage: 'ubuntu-latest'
@ -171,8 +175,9 @@ stages:
- task: CmdLine@2 - task: CmdLine@2
displayName: Migrate to last tagged release displayName: Migrate to last tagged release
inputs: inputs:
script: script: |
pipenv run ./manage.py migrate pipenv run python -m scripts.generate_ci_config
pipenv run python -m lifecycle.migrate
- task: CmdLine@2 - task: CmdLine@2
displayName: Install current branch displayName: Install current branch
inputs: inputs:
@ -184,8 +189,8 @@ stages:
displayName: Migrate to current branch displayName: Migrate to current branch
inputs: inputs:
script: | script: |
pipenv run python -m scripts.generate_ci_config
pipenv run python -m lifecycle.migrate pipenv run python -m lifecycle.migrate
pipenv run ./manage.py migrate
- job: coverage_unittest - job: coverage_unittest
pool: pool:
vmImage: 'ubuntu-latest' vmImage: 'ubuntu-latest'
@ -210,6 +215,7 @@ stages:
displayName: Run full test suite displayName: Run full test suite
inputs: inputs:
script: | script: |
pipenv run python -m scripts.generate_ci_config
pipenv run make test pipenv run make test
- task: CmdLine@2 - task: CmdLine@2
inputs: inputs:
@ -253,6 +259,7 @@ stages:
displayName: Run full test suite displayName: Run full test suite
inputs: inputs:
script: | script: |
pipenv run python -m scripts.generate_ci_config
pipenv run make test-integration pipenv run make test-integration
- task: CmdLine@2 - task: CmdLine@2
inputs: inputs:
@ -308,6 +315,7 @@ stages:
displayName: Run full test suite displayName: Run full test suite
inputs: inputs:
script: | script: |
pipenv run python -m scripts.generate_ci_config
pipenv run make test-e2e pipenv run make test-e2e
- task: CmdLine@2 - task: CmdLine@2
condition: always() condition: always()

View File

@ -21,7 +21,7 @@ services:
networks: networks:
- internal - internal
server: server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.1} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.4}
restart: unless-stopped restart: unless-stopped
command: server command: server
environment: environment:
@ -52,7 +52,7 @@ services:
- "0.0.0.0:9000:9000" - "0.0.0.0:9000:9000"
- "0.0.0.0:9443:9443" - "0.0.0.0:9443:9443"
worker: worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.1} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.4}
restart: unless-stopped restart: unless-stopped
command: worker command: worker
networks: networks:

View File

@ -1,3 +1,3 @@
package constants package constants
const VERSION = "2021.5.1" const VERSION = "2021.5.4"

View File

@ -9,7 +9,18 @@ import (
func (ws *WebServer) configureProxy() { func (ws *WebServer) configureProxy() {
// Reverse proxy to the application server // Reverse proxy to the application server
u, _ := url.Parse("http://localhost:8000") u, _ := url.Parse("http://localhost:8000")
rp := httputil.NewSingleHostReverseProxy(u) director := func(req *http.Request) {
req.URL.Scheme = u.Scheme
req.URL.Host = u.Host
if _, ok := req.Header["User-Agent"]; !ok {
// explicitly disable User-Agent so it's not set to default value
req.Header.Set("User-Agent", "")
}
if req.TLS != nil {
req.Header.Set("X-Forwarded-Proto", "https")
}
}
rp := &httputil.ReverseProxy{Director: director}
rp.ErrorHandler = ws.proxyErrorHandler rp.ErrorHandler = ws.proxyErrorHandler
rp.ModifyResponse = ws.proxyModifyResponse rp.ModifyResponse = ws.proxyModifyResponse
ws.m.PathPrefix("/").Handler(rp) ws.m.PathPrefix("/").Handler(rp)

View File

@ -4,16 +4,19 @@ import (
"net/http" "net/http"
"goauthentik.io/internal/config" "goauthentik.io/internal/config"
"goauthentik.io/internal/constants"
staticWeb "goauthentik.io/web" staticWeb "goauthentik.io/web"
) )
func (ws *WebServer) configureStatic() { func (ws *WebServer) configureStatic() {
statRouter := ws.lh.NewRoute().Subrouter()
if config.G.Debug { if config.G.Debug {
ws.log.Debug("Using local static files") ws.log.Debug("Using local static files")
ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static/dist", http.FileServer(http.Dir("./web/dist")))) ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static/dist", http.FileServer(http.Dir("./web/dist"))))
ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static/authentik", http.FileServer(http.Dir("./web/authentik")))) ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static/authentik", http.FileServer(http.Dir("./web/authentik"))))
} else { } else {
ws.log.Debug("Using packaged static files") statRouter.Use(ws.staticHeaderMiddleware)
ws.log.Debug("Using packaged static files with aggressive caching")
ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticDist)))) ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticDist))))
ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticAuthentik)))) ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticAuthentik))))
} }
@ -41,3 +44,12 @@ func (ws *WebServer) configureStatic() {
// Media files, always local // Media files, always local
ws.lh.PathPrefix("/media").Handler(http.StripPrefix("/media", http.FileServer(http.Dir(config.G.Paths.Media)))) ws.lh.PathPrefix("/media").Handler(http.StripPrefix("/media", http.FileServer(http.Dir(config.G.Paths.Media))))
} }
func (ws *WebServer) staticHeaderMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "\"public, no-transform\"")
w.Header().Set("X-authentik-version", constants.VERSION)
w.Header().Set("Vary", "X-authentik-version")
h.ServeHTTP(w, r)
})
}

View File

@ -5,6 +5,7 @@ printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap",
function check_if_root { function check_if_root {
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
printf '{"event": "Not running as root, disabling permission fixes", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr printf '{"event": "Not running as root, disabling permission fixes", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
$1
return return
fi fi
SOCKET="/var/run/docker.sock" SOCKET="/var/run/docker.sock"
@ -12,18 +13,19 @@ function check_if_root {
# Get group ID of the docker socket, so we can create a matching group and # Get group ID of the docker socket, so we can create a matching group and
# add ourselves to it # add ourselves to it
DOCKER_GID=$(stat -c '%g' $SOCKET) DOCKER_GID=$(stat -c '%g' $SOCKET)
getent group $DOCKER_GID || groupadd -f -g $DOCKER_GID docker
usermod -a -G $DOCKER_GID authentik usermod -a -G $DOCKER_GID authentik
fi fi
# Fix permissions of backups and media # Fix permissions of backups and media
chown -R authentik:authentik /media /backups chown -R authentik:authentik /media /backups
chpst -u authentik env HOME=/authentik $1
} }
if [[ "$1" == "server" ]]; then if [[ "$1" == "server" ]]; then
python -m lifecycle.migrate python -m lifecycle.migrate
/authentik-proxy /authentik-proxy
elif [[ "$1" == "worker" ]]; then elif [[ "$1" == "worker" ]]; then
check_if_root check_if_root "celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events"
chpst -u authentik env HOME=/authentik celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
elif [[ "$1" == "backup" ]]; then elif [[ "$1" == "backup" ]]; then
python -m manage dbbackup --clean python -m manage dbbackup --clean
elif [[ "$1" == "restore" ]]; then elif [[ "$1" == "restore" ]]; then

View File

@ -42,7 +42,7 @@ type APIController struct {
// NewAPIController initialise new API Controller instance from URL and API token // NewAPIController initialise new API Controller instance from URL and API token
func NewAPIController(akURL url.URL, token string) *APIController { func NewAPIController(akURL url.URL, token string) *APIController {
transport := httptransport.New(akURL.Host, client.DefaultBasePath, []string{akURL.Scheme}) transport := httptransport.New(akURL.Host, client.DefaultBasePath, []string{akURL.Scheme})
transport.Transport = SetUserAgent(getTLSTransport(), pkg.UserAgent()) transport.Transport = SetUserAgent(GetTLSTransport(), pkg.UserAgent())
// create the transport // create the transport
auth := httptransport.BearerToken(token) auth := httptransport.BearerToken(token)

View File

@ -52,7 +52,8 @@ func doGlobalSetup(config map[string]interface{}) {
defer sentry.Flush(2 * time.Second) defer sentry.Flush(2 * time.Second)
} }
func getTLSTransport() http.RoundTripper { // GetTLSTransport Get a TLS transport instance, that skips verification if configured via environment variables.
func GetTLSTransport() http.RoundTripper {
value, set := os.LookupEnv("AUTHENTIK_INSECURE") value, set := os.LookupEnv("AUTHENTIK_INSECURE")
if !set { if !set {
value = "false" value = "false"

View File

@ -55,14 +55,18 @@ func (ls *LDAPServer) Start() error {
type transport struct { type transport struct {
headers map[string]string headers map[string]string
inner http.RoundTripper
} }
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
for key, value := range t.headers { for key, value := range t.headers {
req.Header.Add(key, value) req.Header.Add(key, value)
} }
return http.DefaultTransport.RoundTrip(req) return t.inner.RoundTrip(req)
} }
func newTransport(headers map[string]string) *transport { func newTransport(inner http.RoundTripper, headers map[string]string) *transport {
return &transport{headers} return &transport{
inner: inner,
headers: headers,
}
} }

View File

@ -14,6 +14,8 @@ import (
goldap "github.com/go-ldap/ldap/v3" goldap "github.com/go-ldap/ldap/v3"
httptransport "github.com/go-openapi/runtime/client" httptransport "github.com/go-openapi/runtime/client"
"github.com/nmcclain/ldap" "github.com/nmcclain/ldap"
"goauthentik.io/outpost/pkg"
"goauthentik.io/outpost/pkg/ak"
"goauthentik.io/outpost/pkg/client/core" "goauthentik.io/outpost/pkg/client/core"
"goauthentik.io/outpost/pkg/client/flows" "goauthentik.io/outpost/pkg/client/flows"
"goauthentik.io/outpost/pkg/models" "goauthentik.io/outpost/pkg/models"
@ -61,7 +63,7 @@ func (pi *ProviderInstance) Bind(username string, bindDN, bindPW string, conn ne
// Create new http client that also sets the correct ip // Create new http client that also sets the correct ip
client := &http.Client{ client := &http.Client{
Jar: jar, Jar: jar,
Transport: newTransport(map[string]string{ Transport: newTransport(ak.SetUserAgent(ak.GetTLSTransport(), pkg.UserAgent()), map[string]string{
"X-authentik-remote-ip": host, "X-authentik-remote-ip": host,
}), }),
} }

View File

@ -117,7 +117,7 @@ func (pi *ProviderInstance) Search(bindDN string, searchReq ldap.SearchRequest,
attrs = append(attrs, AKAttrsToLDAP(u.Attributes)...) attrs = append(attrs, AKAttrsToLDAP(u.Attributes)...)
dn := fmt.Sprintf("cn=%s,%s", *u.Name, pi.UserDN) dn := fmt.Sprintf("cn=%s,%s", *u.Username, pi.UserDN)
entries = append(entries, &ldap.Entry{DN: dn, Attributes: attrs}) entries = append(entries, &ldap.Entry{DN: dn, Attributes: attrs})
} }
} }

View File

@ -80,19 +80,19 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
ID: "default", ID: "default",
URI: provider.InternalHost, URI: provider.InternalHost,
Path: "/", Path: "/",
InsecureSkipTLSVerify: provider.InternalHostSslValidation, InsecureSkipTLSVerify: !provider.InternalHostSslValidation,
}, },
} }
} }
if provider.Certificate != nil { if provider.Certificate != nil {
pb.log.WithField("provider", provider.ClientID).Debug("Enabling TLS") pb.log.WithField("provider", provider.Name).Debug("Enabling TLS")
cert, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewCertificate(&crypto.CryptoCertificatekeypairsViewCertificateParams{ cert, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewCertificate(&crypto.CryptoCertificatekeypairsViewCertificateParams{
Context: context.Background(), Context: context.Background(),
KpUUID: *provider.Certificate, KpUUID: *provider.Certificate,
}, pb.s.ak.Auth) }, pb.s.ak.Auth)
if err != nil { if err != nil {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to fetch certificate") pb.log.WithField("provider", provider.Name).WithError(err).Warning("Failed to fetch certificate")
return providerOpts return providerOpts
} }
key, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewPrivateKey(&crypto.CryptoCertificatekeypairsViewPrivateKeyParams{ key, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewPrivateKey(&crypto.CryptoCertificatekeypairsViewPrivateKeyParams{
@ -100,17 +100,17 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
KpUUID: *provider.Certificate, KpUUID: *provider.Certificate,
}, pb.s.ak.Auth) }, pb.s.ak.Auth)
if err != nil { if err != nil {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to fetch private key") pb.log.WithField("provider", provider.Name).WithError(err).Warning("Failed to fetch private key")
return providerOpts return providerOpts
} }
x509cert, err := tls.X509KeyPair([]byte(cert.Payload.Data), []byte(key.Payload.Data)) x509cert, err := tls.X509KeyPair([]byte(cert.Payload.Data), []byte(key.Payload.Data))
if err != nil { if err != nil {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to parse certificate") pb.log.WithField("provider", provider.Name).WithError(err).Warning("Failed to parse certificate")
return providerOpts return providerOpts
} }
pb.cert = &x509cert pb.cert = &x509cert
pb.log.WithField("provider", provider.ClientID).Debug("Loaded certificates") pb.log.WithField("provider", provider.Name).Debug("Loaded certificates")
} }
return providerOpts return providerOpts
} }

View File

@ -184,7 +184,7 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
return return
} }
session, err := p.redeemCode(req.Context(), getHost(req), req.Form.Get("code")) session, err := p.redeemCode(req.Context(), req.Host, req.Form.Get("code"))
if err != nil { if err != nil {
p.logger.Errorf("Error redeeming code during OAuth2 callback: %v", err) p.logger.Errorf("Error redeeming code during OAuth2 callback: %v", err)
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error") p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
@ -207,7 +207,7 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
} }
p.ClearCSRFCookie(rw, req) p.ClearCSRFCookie(rw, req)
if c.Value != nonce { if c.Value != nonce {
p.logger.WithField("user", session.Email).WithField("status", "AuthFailure").Info("Invalid authentication via OAuth2: CSRF token mismatch, potential attack") p.logger.WithField("is", c.Value).WithField("should", nonce).WithField("user", session.Email).WithField("status", "AuthFailure").Info("Invalid authentication via OAuth2: CSRF token mismatch, potential attack")
p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", "CSRF Failed") p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", "CSRF Failed")
return return
} }

View File

@ -13,12 +13,14 @@ func getTemplates() *template.Template {
<head> <head>
<title>{{.Title}}</title> <title>{{.Title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>* { font-family: sans-serif; }</style>
</head> </head>
<body> <body>
<h2>{{.Title}}</h2> <h2>{{.Title}}</h2>
<p>{{.Message}}</p> <p>{{.Message}}</p>
<hr> <hr>
<p><a href="{{.ProxyPrefix}}/sign_in">Sign In</a></p> <p><a href="{{.ProxyPrefix}}/sign_in">Sign In</a></p>
<p>Powered by <a href="https://goauthentik.io">authentik</a></p>
</body> </body>
</html>{{end}}`) </html>{{end}}`)
if err != nil { if err != nil {

View File

@ -5,7 +5,7 @@ import (
"os" "os"
) )
const VERSION = "2021.5.1" const VERSION = "2021.5.4"
func BUILD() string { func BUILD() string {
return os.Getenv("GIT_BUILD_HASH") return os.Getenv("GIT_BUILD_HASH")

View File

@ -1,16 +0,0 @@
#!/bin/bash -xe
wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
VERSION=3.9.0
wget https://www.python.org/ftp/python/$VERSION/Python-$VERSION.tgz
tar xvzf Python-$VERSION.tgz
cd Python-$VERSION/
./configure --prefix=$HOME/_work/_tool/Python/$VERSION/x64/ --enable-optimizations --with-ensurepip=install
make -j 8
sudo make altinstall
touch $HOME/_work/_tool/Python/$VERSION/x64.complete
ln -s $HOME/_work/_tool/Python/3.9.5/x64 $HOME/_work/_tool/Python/3/x64
ln -s $HOME/_work/_tool/Python/3.9.5/x64 $HOME/_work/_tool/Python/3.9/x64

View File

@ -0,0 +1,8 @@
"""Utility script to generate a config for CI runs"""
from authentik.providers.oauth2.generators import generate_client_id
from yaml import safe_dump
with open("local.env.yml", "w") as _config:
safe_dump({
"secret_key": generate_client_id()
}, _config, default_flow_style=False)

View File

@ -531,6 +531,11 @@ paths:
description: '' description: ''
required: false required: false
type: string type: string
- name: ordering
in: query
description: Which field to use when ordering the results.
required: false
type: string
- name: search - name: search
in: query in: query
description: A search term. description: A search term.
@ -590,30 +595,6 @@ paths:
$ref: '#/definitions/GenericError' $ref: '#/definitions/GenericError'
tags: tags:
- authenticators - authenticators
post:
operationId: authenticators_static_create
description: Viewset for static authenticator devices
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/StaticDevice'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/StaticDevice'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- authenticators
parameters: [] parameters: []
/authenticators/static/{id}/: /authenticators/static/{id}/:
get: get:
@ -792,30 +773,6 @@ paths:
$ref: '#/definitions/GenericError' $ref: '#/definitions/GenericError'
tags: tags:
- authenticators - authenticators
post:
operationId: authenticators_totp_create
description: Viewset for totp authenticator devices
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/TOTPDevice'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/TOTPDevice'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- authenticators
parameters: [] parameters: []
/authenticators/totp/{id}/: /authenticators/totp/{id}/:
get: get:
@ -994,30 +951,6 @@ paths:
$ref: '#/definitions/GenericError' $ref: '#/definitions/GenericError'
tags: tags:
- authenticators - authenticators
post:
operationId: authenticators_webauthn_create
description: Viewset for WebAuthn authenticator devices
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/WebAuthnDevice'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/WebAuthnDevice'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- authenticators
parameters: [] parameters: []
/authenticators/webauthn/{id}/: /authenticators/webauthn/{id}/:
get: get:
@ -10420,30 +10353,6 @@ paths:
$ref: '#/definitions/GenericError' $ref: '#/definitions/GenericError'
tags: tags:
- sources - sources
post:
operationId: sources_oauth_user_connections_create
description: Source Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/UserOAuthSourceConnection'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/UserOAuthSourceConnection'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- sources
parameters: [] parameters: []
/sources/oauth_user_connections/{id}/: /sources/oauth_user_connections/{id}/:
get: get:
@ -18040,6 +17949,7 @@ definitions:
required: required:
- name - name
- slug - slug
- plex_token
type: object type: object
properties: properties:
pk: pk:

View File

@ -46,7 +46,7 @@ class TestProviderProxy(SeleniumTestCase):
"""Start proxy container based on outpost created""" """Start proxy container based on outpost created"""
client: DockerClient = from_env() client: DockerClient = from_env()
container = client.containers.run( container = client.containers.run(
image=f"beryju/authentik-proxy:{__version__}", image=f"ghcr.io/goauthentik/proxy:{__version__}",
detach=True, detach=True,
network_mode="host", network_mode="host",
auto_remove=True, auto_remove=True,

View File

@ -1,98 +0,0 @@
worker_processes auto;
pid /tmp/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
error_log /dev/stdout;
user www-data;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
log_format json_combined escape=json
'{'
'"timestamp":"$time_local",'
'"host":"$remote_addr",'
'"request_username":"$remote_user",'
'"event":"$request",'
'"status": "$status",'
'"size":"$body_bytes_sent",'
'"runtime":"$request_time",'
'"logger":"nginx",'
'"request_useragent":"$http_user_agent"'
'}';
access_log /dev/null json_combined;
##
# Gzip Settings
##
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
server {
listen 80;
server_name _;
charset utf-8;
root /usr/share/nginx/html;
index index.html;
location / {
access_log /dev/stdout json_combined;
}
location /static/ {
expires 31d;
add_header Cache-Control "public, no-transform";
add_header X-authentik-version "2021.5.1";
add_header Vary X-authentik-version;
}
location /if/admin {
root /usr/share/nginx/html/static/dist;
try_files $uri /static/dist/if/admin/index.html;
}
location /if/flow {
root /usr/share/nginx/html/static/dist;
try_files $uri /static/dist/if/flow/index.html;
}
}
}

28
web/package-lock.json generated
View File

@ -42,13 +42,13 @@
"eslint": "^7.26.0", "eslint": "^7.26.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.2", "eslint-plugin-custom-elements": "0.0.2",
"eslint-plugin-lit": "^1.4.0", "eslint-plugin-lit": "^1.4.1",
"flowchart.js": "^1.15.0", "flowchart.js": "^1.15.0",
"lit-element": "^2.5.1", "lit-element": "^2.5.1",
"lit-html": "^1.4.1", "lit-html": "^1.4.1",
"moment": "^2.29.1", "moment": "^2.29.1",
"rapidoc": "^9.0.0", "rapidoc": "^9.0.0",
"rollup": "^2.47.0", "rollup": "^2.48.0",
"rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-copy": "^3.4.0", "rollup-plugin-copy": "^3.4.0",
"rollup-plugin-cssimport": "^1.0.2", "rollup-plugin-cssimport": "^1.0.2",
@ -3601,9 +3601,9 @@
} }
}, },
"node_modules/eslint-plugin-lit": { "node_modules/eslint-plugin-lit": {
"version": "1.4.0", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.4.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.4.1.tgz",
"integrity": "sha512-3PJCC1p4pvDBKtFmg1g2cGzAgJF4IDqhb9NJUh95nYc+QXExa/O/0fILF4WB6X7qdNQKm+gW6nYtSKTyYPHtXw==", "integrity": "sha512-7UIbjSa1DGH7ZaDhmGZPHWm17kOjCrGP4VAKNjR0wZVdQLuRKXE+LqXysQ1L3O12hBnExkMG2J9swXpQvuCuXA==",
"dependencies": { "dependencies": {
"parse5": "^6.0.1", "parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1", "parse5-htmlparser2-tree-adapter": "^6.0.1",
@ -6408,9 +6408,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "2.47.0", "version": "2.48.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.47.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz",
"integrity": "sha512-rqBjgq9hQfW0vRmz+0S062ORRNJXvwRpzxhFXORvar/maZqY6za3rgQ/p1Glg+j1hnc1GtYyQCPiAei95uTElg==", "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==",
"bin": { "bin": {
"rollup": "dist/bin/rollup" "rollup": "dist/bin/rollup"
}, },
@ -10751,9 +10751,9 @@
} }
}, },
"eslint-plugin-lit": { "eslint-plugin-lit": {
"version": "1.4.0", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.4.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.4.1.tgz",
"integrity": "sha512-3PJCC1p4pvDBKtFmg1g2cGzAgJF4IDqhb9NJUh95nYc+QXExa/O/0fILF4WB6X7qdNQKm+gW6nYtSKTyYPHtXw==", "integrity": "sha512-7UIbjSa1DGH7ZaDhmGZPHWm17kOjCrGP4VAKNjR0wZVdQLuRKXE+LqXysQ1L3O12hBnExkMG2J9swXpQvuCuXA==",
"requires": { "requires": {
"parse5": "^6.0.1", "parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1", "parse5-htmlparser2-tree-adapter": "^6.0.1",
@ -12917,9 +12917,9 @@
} }
}, },
"rollup": { "rollup": {
"version": "2.47.0", "version": "2.48.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.47.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz",
"integrity": "sha512-rqBjgq9hQfW0vRmz+0S062ORRNJXvwRpzxhFXORvar/maZqY6za3rgQ/p1Glg+j1hnc1GtYyQCPiAei95uTElg==", "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==",
"requires": { "requires": {
"fsevents": "~2.3.1" "fsevents": "~2.3.1"
} }

View File

@ -68,13 +68,13 @@
"eslint": "^7.26.0", "eslint": "^7.26.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.2", "eslint-plugin-custom-elements": "0.0.2",
"eslint-plugin-lit": "^1.4.0", "eslint-plugin-lit": "^1.4.1",
"flowchart.js": "^1.15.0", "flowchart.js": "^1.15.0",
"lit-element": "^2.5.1", "lit-element": "^2.5.1",
"lit-html": "^1.4.1", "lit-html": "^1.4.1",
"moment": "^2.29.1", "moment": "^2.29.1",
"rapidoc": "^9.0.0", "rapidoc": "^9.0.0",
"rollup": "^2.47.0", "rollup": "^2.48.0",
"rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-copy": "^3.4.0", "rollup-plugin-copy": "^3.4.0",
"rollup-plugin-cssimport": "^1.0.2", "rollup-plugin-cssimport": "^1.0.2",

View File

@ -104,6 +104,7 @@ export default [
dir: "dist", dir: "dist",
sourcemap: true, sourcemap: true,
manualChunks: manualChunks, manualChunks: manualChunks,
chunkFileNames: "admin-[name].js"
}, },
], ],
plugins: [ plugins: [
@ -135,6 +136,7 @@ export default [
dir: "dist", dir: "dist",
sourcemap: true, sourcemap: true,
manualChunks: manualChunks, manualChunks: manualChunks,
chunkFileNames: "flow-[name].js"
}, },
], ],
plugins: [ plugins: [

View File

@ -6,7 +6,9 @@ import { me } from "./Users";
import { config } from "./Config"; import { config } from "./Config";
import { Config } from "authentik-api"; import { Config } from "authentik-api";
export function configureSentry(canDoPpi: boolean = false): Promise<Config> { export const TAG_SENTRY_COMPONENT = "authentik:component";
export function configureSentry(canDoPpi: boolean = false, tags: { [key: string]: string; } = {}): Promise<Config> {
return config().then((config) => { return config().then((config) => {
if (config.errorReportingEnabled) { if (config.errorReportingEnabled) {
Sentry.init({ Sentry.init({
@ -51,6 +53,12 @@ export function configureSentry(canDoPpi: boolean = false): Promise<Config> {
return event; return event;
}, },
}); });
Sentry.setTags(tags);
if (window.location.pathname.includes("if/")) {
// Get the interface name from URL
const intf = window.location.pathname.replace(/.+if\/(.+)\//, "$1");
Sentry.setTag(TAG_SENTRY_COMPONENT, `web/${intf}`);
}
console.debug("authentik/config: Sentry enabled."); console.debug("authentik/config: Sentry enabled.");
if (config.errorReportingSendPii && canDoPpi) { if (config.errorReportingSendPii && canDoPpi) {
me().then(user => { me().then(user => {

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger"; export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress"; export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current"; export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2021.5.1"; export const VERSION = "2021.5.4";
export const PAGE_SIZE = 20; export const PAGE_SIZE = 20;
export const EVENT_REFRESH = "ak-refresh"; export const EVENT_REFRESH = "ak-refresh";
export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle"; export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle";

View File

@ -55,7 +55,7 @@ export class ModalButton extends LitElement {
resetForms(): void { resetForms(): void {
this.querySelectorAll<HTMLFormElement>("[slot=form]").forEach(form => { this.querySelectorAll<HTMLFormElement>("[slot=form]").forEach(form => {
form.reset(); form?.reset();
}); });
} }

View File

@ -29,8 +29,8 @@ export class TokenCopyButton extends ActionButton {
this.buttonClass = PRIMARY_CLASS; this.buttonClass = PRIMARY_CLASS;
}, 1500); }, 1500);
}); });
}).catch((err: Response) => { }).catch((err: Response | undefined) => {
return err.json().then(errResp => { return err?.json().then(errResp => {
throw new Error(errResp["detail"]); throw new Error(errResp["detail"]);
}); });
}); });

View File

@ -76,10 +76,7 @@ export class Form<T> extends LitElement {
*/ */
reset(): void { reset(): void {
const ironForm = this.shadowRoot?.querySelector("iron-form"); const ironForm = this.shadowRoot?.querySelector("iron-form");
if (!ironForm) { ironForm?.reset();
return;
}
ironForm.reset();
} }
/** /**

View File

@ -23,7 +23,7 @@ export class ModalForm extends ModalButton {
return formPromise.then(() => { return formPromise.then(() => {
if (this.closeAfterSuccessfulSubmit) { if (this.closeAfterSuccessfulSubmit) {
this.open = false; this.open = false;
form.reset(); form?.reset();
} }
this.dispatchEvent( this.dispatchEvent(
new CustomEvent(EVENT_REFRESH, { new CustomEvent(EVENT_REFRESH, {

View File

@ -34,7 +34,7 @@ export abstract class TableModal<T> extends Table<T> {
resetForms(): void { resetForms(): void {
this.querySelectorAll<HTMLFormElement>("[slot=form]").forEach(form => { this.querySelectorAll<HTMLFormElement>("[slot=form]").forEach(form => {
form.reset(); form?.reset();
}); });
} }

View File

@ -10,9 +10,8 @@
<link rel="stylesheet" type="text/css" href="/static/dist/empty-state.css"> <link rel="stylesheet" type="text/css" href="/static/dist/empty-state.css">
<link rel="stylesheet" type="text/css" href="/static/dist/spinner.css"> <link rel="stylesheet" type="text/css" href="/static/dist/spinner.css">
<link rel="stylesheet" type="text/css" href="/static/dist/authentik.css"> <link rel="stylesheet" type="text/css" href="/static/dist/authentik.css">
<script>ShadyDOM = { force: !navigator.webdriver };</script> <script>ShadyDOM = { force: !navigator.webdriver }; window["polymerSkipLoadingFontRoboto"] = true;</script>
<script src="/static/dist/poly.js" type="module"></script> <script src="/static/dist/poly.js" type="module"></script>
<script>window["polymerSkipLoadingFontRoboto"] = true;</script>
<script src="/static/dist/FlowInterface.js" type="module"></script> <script src="/static/dist/FlowInterface.js" type="module"></script>
<title>authentik</title> <title>authentik</title>
</head> </head>

View File

@ -144,7 +144,7 @@ msgstr "Algorithm used to sign the JWT Tokens."
msgid "Allow IDP-initiated logins" msgid "Allow IDP-initiated logins"
msgstr "Allow IDP-initiated logins" msgstr "Allow IDP-initiated logins"
#: src/pages/sources/plex/PlexSourceForm.ts:150 #: src/pages/sources/plex/PlexSourceForm.ts:103
msgid "Allow friends to authenticate via Plex, even if you don't share any servers" msgid "Allow friends to authenticate via Plex, even if you don't share any servers"
msgstr "Allow friends to authenticate via Plex, even if you don't share any servers" msgstr "Allow friends to authenticate via Plex, even if you don't share any servers"
@ -152,7 +152,7 @@ msgstr "Allow friends to authenticate via Plex, even if you don't share any serv
msgid "Allow up to N occurrences in the HIBP database." msgid "Allow up to N occurrences in the HIBP database."
msgstr "Allow up to N occurrences in the HIBP database." msgstr "Allow up to N occurrences in the HIBP database."
#: src/pages/policies/PolicyListPage.ts:41 #: src/pages/policies/PolicyListPage.ts:42
msgid "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages." msgid "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages."
msgstr "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages." msgstr "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages."
@ -164,7 +164,7 @@ msgstr "Allowed Redirect URIs"
msgid "Allowed count" msgid "Allowed count"
msgstr "Allowed count" msgstr "Allowed count"
#: src/pages/sources/plex/PlexSourceForm.ts:155 #: src/pages/sources/plex/PlexSourceForm.ts:108
msgid "Allowed servers" msgid "Allowed servers"
msgstr "Allowed servers" msgstr "Allowed servers"
@ -218,6 +218,22 @@ msgstr "Applications"
msgid "Apps with most usage" msgid "Apps with most usage"
msgstr "Apps with most usage" msgstr "Apps with most usage"
#: src/pages/flows/FlowListPage.ts:146
msgid ""
"Are you sure you want to clear the flow cache?\n"
"This will cause all flows to be re-evaluated on their next usage."
msgstr ""
"Are you sure you want to clear the flow cache?\n"
"This will cause all flows to be re-evaluated on their next usage."
#: src/pages/policies/PolicyListPage.ts:165
msgid ""
"Are you sure you want to clear the policy cache?\n"
"This will cause all policies to be re-evaluated on their next usage."
msgstr ""
"Are you sure you want to clear the policy cache?\n"
"This will cause all policies to be re-evaluated on their next usage."
#: src/elements/forms/DeleteForm.ts:69 #: src/elements/forms/DeleteForm.ts:69
msgid "Are you sure you want to delete {0} {objName} ?" msgid "Are you sure you want to delete {0} {objName} ?"
msgstr "Are you sure you want to delete {0} {objName} ?" msgstr "Are you sure you want to delete {0} {objName} ?"
@ -250,7 +266,7 @@ msgstr "Assertions is empty"
msgid "Assigned to application" msgid "Assigned to application"
msgstr "Assigned to application" msgstr "Assigned to application"
#: src/pages/policies/PolicyListPage.ts:68 #: src/pages/policies/PolicyListPage.ts:69
msgid "Assigned to {0} objects." msgid "Assigned to {0} objects."
msgstr "Assigned to {0} objects." msgstr "Assigned to {0} objects."
@ -282,7 +298,7 @@ msgid "Authentication"
msgstr "Authentication" msgstr "Authentication"
#: src/pages/sources/oauth/OAuthSourceForm.ts:231 #: src/pages/sources/oauth/OAuthSourceForm.ts:231
#: src/pages/sources/plex/PlexSourceForm.ts:185 #: src/pages/sources/plex/PlexSourceForm.ts:190
#: src/pages/sources/saml/SAMLSourceForm.ts:243 #: src/pages/sources/saml/SAMLSourceForm.ts:243
msgid "Authentication flow" msgid "Authentication flow"
msgstr "Authentication flow" msgstr "Authentication flow"
@ -530,6 +546,21 @@ msgstr "Checks if the request's user's password has been changed in the last x d
msgid "Checks the value from the policy request against several rules, mostly used to ensure password strength." msgid "Checks the value from the policy request against several rules, mostly used to ensure password strength."
msgstr "Checks the value from the policy request against several rules, mostly used to ensure password strength." msgstr "Checks the value from the policy request against several rules, mostly used to ensure password strength."
#: src/pages/flows/FlowListPage.ts:143
msgid "Clear Flow cache"
msgstr "Clear Flow cache"
#: src/pages/policies/PolicyListPage.ts:162
msgid "Clear Policy cache"
msgstr "Clear Policy cache"
#: src/pages/flows/FlowListPage.ts:138
#: src/pages/flows/FlowListPage.ts:150
#: src/pages/policies/PolicyListPage.ts:157
#: src/pages/policies/PolicyListPage.ts:169
msgid "Clear cache"
msgstr "Clear cache"
#: src/elements/forms/HorizontalFormElement.ts:82 #: src/elements/forms/HorizontalFormElement.ts:82
msgid "Click to change value" msgid "Click to change value"
msgstr "Click to change value" msgstr "Click to change value"
@ -540,7 +571,7 @@ msgstr "Click to copy token"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99
#: src/pages/sources/plex/PlexSourceForm.ts:141 #: src/pages/sources/plex/PlexSourceForm.ts:176
msgid "Client ID" msgid "Client ID"
msgstr "Client ID" msgstr "Client ID"
@ -726,8 +757,8 @@ msgstr "Copy download URL"
#: src/pages/flows/BoundStagesList.ts:119 #: src/pages/flows/BoundStagesList.ts:119
#: src/pages/flows/BoundStagesList.ts:146 #: src/pages/flows/BoundStagesList.ts:146
#: src/pages/flows/BoundStagesList.ts:167 #: src/pages/flows/BoundStagesList.ts:167
#: src/pages/flows/FlowListPage.ts:109 #: src/pages/flows/FlowListPage.ts:110
#: src/pages/flows/FlowListPage.ts:117 #: src/pages/flows/FlowListPage.ts:118
#: src/pages/groups/GroupListPage.ts:90 #: src/pages/groups/GroupListPage.ts:90
#: src/pages/groups/GroupListPage.ts:98 #: src/pages/groups/GroupListPage.ts:98
#: src/pages/outposts/OutpostListPage.ts:101 #: src/pages/outposts/OutpostListPage.ts:101
@ -737,8 +768,8 @@ msgstr "Copy download URL"
#: src/pages/policies/BoundPoliciesList.ts:162 #: src/pages/policies/BoundPoliciesList.ts:162
#: src/pages/policies/BoundPoliciesList.ts:189 #: src/pages/policies/BoundPoliciesList.ts:189
#: src/pages/policies/BoundPoliciesList.ts:210 #: src/pages/policies/BoundPoliciesList.ts:210
#: src/pages/policies/PolicyListPage.ts:124 #: src/pages/policies/PolicyListPage.ts:125
#: src/pages/policies/PolicyListPage.ts:133 #: src/pages/policies/PolicyListPage.ts:134
#: src/pages/property-mappings/PropertyMappingListPage.ts:113 #: src/pages/property-mappings/PropertyMappingListPage.ts:113
#: src/pages/property-mappings/PropertyMappingListPage.ts:122 #: src/pages/property-mappings/PropertyMappingListPage.ts:122
#: src/pages/providers/ProviderListPage.ts:108 #: src/pages/providers/ProviderListPage.ts:108
@ -778,7 +809,7 @@ msgstr "Create Binding"
msgid "Create Certificate-Key Pair" msgid "Create Certificate-Key Pair"
msgstr "Create Certificate-Key Pair" msgstr "Create Certificate-Key Pair"
#: src/pages/flows/FlowListPage.ts:112 #: src/pages/flows/FlowListPage.ts:113
msgid "Create Flow" msgid "Create Flow"
msgstr "Create Flow" msgstr "Create Flow"
@ -840,7 +871,7 @@ msgstr "Create provider"
#: src/pages/flows/BoundStagesList.ts:149 #: src/pages/flows/BoundStagesList.ts:149
#: src/pages/outposts/ServiceConnectionListPage.ts:122 #: src/pages/outposts/ServiceConnectionListPage.ts:122
#: src/pages/policies/BoundPoliciesList.ts:192 #: src/pages/policies/BoundPoliciesList.ts:192
#: src/pages/policies/PolicyListPage.ts:136 #: src/pages/policies/PolicyListPage.ts:137
#: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:120 #: src/pages/providers/ProviderListPage.ts:120
#: src/pages/sources/SourcesListPage.ts:126 #: src/pages/sources/SourcesListPage.ts:126
@ -892,11 +923,11 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/pages/crypto/CertificateKeyPairListPage.ts:86 #: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82 #: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86 #: src/pages/events/TransportListPage.ts:86
#: src/pages/flows/FlowListPage.ts:86 #: src/pages/flows/FlowListPage.ts:87
#: src/pages/groups/GroupListPage.ts:81 #: src/pages/groups/GroupListPage.ts:81
#: src/pages/outposts/OutpostListPage.ts:87 #: src/pages/outposts/OutpostListPage.ts:87
#: src/pages/outposts/ServiceConnectionListPage.ts:101 #: src/pages/outposts/ServiceConnectionListPage.ts:101
#: src/pages/policies/PolicyListPage.ts:115 #: src/pages/policies/PolicyListPage.ts:116
#: src/pages/property-mappings/PropertyMappingListPage.ts:104 #: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:99 #: src/pages/providers/ProviderListPage.ts:99
#: src/pages/sources/SourcesListPage.ts:95 #: src/pages/sources/SourcesListPage.ts:95
@ -967,7 +998,7 @@ msgid "Designates whether this user should be treated as active. Unselect this i
msgstr "Designates whether this user should be treated as active. Unselect this instead of deleting accounts." msgstr "Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
#: src/pages/flows/FlowForm.ts:119 #: src/pages/flows/FlowForm.ts:119
#: src/pages/flows/FlowListPage.ts:48 #: src/pages/flows/FlowListPage.ts:49
msgid "Designation" msgid "Designation"
msgstr "Designation" msgstr "Designation"
@ -1049,11 +1080,11 @@ msgstr "Each provider has a different issuer, based on the application slug."
#: src/pages/crypto/CertificateKeyPairListPage.ts:74 #: src/pages/crypto/CertificateKeyPairListPage.ts:74
#: src/pages/events/RuleListPage.ts:70 #: src/pages/events/RuleListPage.ts:70
#: src/pages/events/TransportListPage.ts:74 #: src/pages/events/TransportListPage.ts:74
#: src/pages/flows/FlowListPage.ts:74 #: src/pages/flows/FlowListPage.ts:75
#: src/pages/groups/GroupListPage.ts:69 #: src/pages/groups/GroupListPage.ts:69
#: src/pages/outposts/OutpostListPage.ts:75 #: src/pages/outposts/OutpostListPage.ts:75
#: src/pages/outposts/ServiceConnectionListPage.ts:89 #: src/pages/outposts/ServiceConnectionListPage.ts:89
#: src/pages/policies/PolicyListPage.ts:90 #: src/pages/policies/PolicyListPage.ts:91
#: src/pages/property-mappings/PropertyMappingListPage.ts:79 #: src/pages/property-mappings/PropertyMappingListPage.ts:79
#: src/pages/providers/ProviderListPage.ts:87 #: src/pages/providers/ProviderListPage.ts:87
#: src/pages/providers/ldap/LDAPProviderViewPage.ts:103 #: src/pages/providers/ldap/LDAPProviderViewPage.ts:103
@ -1148,7 +1179,7 @@ msgstr "Enable this if you don't want to use this provider as a proxy, and want
#: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/policies/PolicyBindingForm.ts:199
#: src/pages/sources/ldap/LDAPSourceForm.ts:67 #: src/pages/sources/ldap/LDAPSourceForm.ts:67
#: src/pages/sources/oauth/OAuthSourceForm.ts:134 #: src/pages/sources/oauth/OAuthSourceForm.ts:134
#: src/pages/sources/plex/PlexSourceForm.ts:108 #: src/pages/sources/plex/PlexSourceForm.ts:143
#: src/pages/sources/saml/SAMLSourceForm.ts:67 #: src/pages/sources/saml/SAMLSourceForm.ts:67
msgid "Enabled" msgid "Enabled"
msgstr "Enabled" msgstr "Enabled"
@ -1158,7 +1189,7 @@ msgid "Enrollment"
msgstr "Enrollment" msgstr "Enrollment"
#: src/pages/sources/oauth/OAuthSourceForm.ts:252 #: src/pages/sources/oauth/OAuthSourceForm.ts:252
#: src/pages/sources/plex/PlexSourceForm.ts:206 #: src/pages/sources/plex/PlexSourceForm.ts:211
#: src/pages/sources/saml/SAMLSourceForm.ts:264 #: src/pages/sources/saml/SAMLSourceForm.ts:264
#: src/pages/stages/identification/IdentificationStageForm.ts:104 #: src/pages/stages/identification/IdentificationStageForm.ts:104
msgid "Enrollment flow" msgid "Enrollment flow"
@ -1225,12 +1256,12 @@ msgstr "Events"
msgid "Exception" msgid "Exception"
msgstr "Exception" msgstr "Exception"
#: src/pages/flows/FlowListPage.ts:98 #: src/pages/flows/FlowListPage.ts:99
#: src/pages/flows/FlowViewPage.ts:83 #: src/pages/flows/FlowViewPage.ts:75
msgid "Execute" msgid "Execute"
msgstr "Execute" msgstr "Execute"
#: src/pages/flows/FlowViewPage.ts:69 #: src/pages/flows/FlowViewPage.ts:61
msgid "Execute flow" msgid "Execute flow"
msgstr "Execute flow" msgstr "Execute flow"
@ -1277,7 +1308,7 @@ msgstr "Expiry date"
msgid "Explicit Consent" msgid "Explicit Consent"
msgstr "Explicit Consent" msgstr "Explicit Consent"
#: src/pages/flows/FlowListPage.ts:101 #: src/pages/flows/FlowListPage.ts:102
msgid "Export" msgid "Export"
msgstr "Export" msgstr "Export"
@ -1316,6 +1347,14 @@ msgstr "Failed attempts before cancel"
msgid "Failed sources" msgid "Failed sources"
msgstr "Failed sources" msgstr "Failed sources"
#: src/pages/flows/FlowListPage.ts:137
msgid "Failed to delete flow cache"
msgstr "Failed to delete flow cache"
#: src/pages/policies/PolicyListPage.ts:156
msgid "Failed to delete policy cache"
msgstr "Failed to delete policy cache"
#: src/elements/forms/DeleteForm.ts:46 #: src/elements/forms/DeleteForm.ts:46
msgid "Failed to delete {0}: {1}" msgid "Failed to delete {0}: {1}"
msgstr "Failed to delete {0}: {1}" msgstr "Failed to delete {0}: {1}"
@ -1358,7 +1397,7 @@ msgid "Fields a user can identify themselves with. If no fields are selected, th
msgstr "Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources." msgstr "Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources."
#: src/pages/flows/FlowImportForm.ts:34 #: src/pages/flows/FlowImportForm.ts:34
#: src/pages/flows/FlowListPage.ts:79 #: src/pages/flows/FlowListPage.ts:80
msgid "Flow" msgid "Flow"
msgstr "Flow" msgstr "Flow"
@ -1367,19 +1406,19 @@ msgid "Flow Overview"
msgstr "Flow Overview" msgstr "Flow Overview"
#: src/pages/sources/oauth/OAuthSourceForm.ts:227 #: src/pages/sources/oauth/OAuthSourceForm.ts:227
#: src/pages/sources/plex/PlexSourceForm.ts:181 #: src/pages/sources/plex/PlexSourceForm.ts:186
#: src/pages/sources/saml/SAMLSourceForm.ts:218 #: src/pages/sources/saml/SAMLSourceForm.ts:218
msgid "Flow settings" msgid "Flow settings"
msgstr "Flow settings" msgstr "Flow settings"
#: src/pages/sources/oauth/OAuthSourceForm.ts:249 #: src/pages/sources/oauth/OAuthSourceForm.ts:249
#: src/pages/sources/plex/PlexSourceForm.ts:203 #: src/pages/sources/plex/PlexSourceForm.ts:208
#: src/pages/sources/saml/SAMLSourceForm.ts:261 #: src/pages/sources/saml/SAMLSourceForm.ts:261
msgid "Flow to use when authenticating existing users." msgid "Flow to use when authenticating existing users."
msgstr "Flow to use when authenticating existing users." msgstr "Flow to use when authenticating existing users."
#: src/pages/sources/oauth/OAuthSourceForm.ts:270 #: src/pages/sources/oauth/OAuthSourceForm.ts:270
#: src/pages/sources/plex/PlexSourceForm.ts:224 #: src/pages/sources/plex/PlexSourceForm.ts:229
#: src/pages/sources/saml/SAMLSourceForm.ts:282 #: src/pages/sources/saml/SAMLSourceForm.ts:282
msgid "Flow to use when enrolling new users." msgid "Flow to use when enrolling new users."
msgstr "Flow to use when enrolling new users." msgstr "Flow to use when enrolling new users."
@ -1411,12 +1450,12 @@ msgstr "Flow used when authorizing this provider."
#: src/interfaces/AdminInterface.ts:82 #: src/interfaces/AdminInterface.ts:82
#: src/interfaces/AdminInterface.ts:84 #: src/interfaces/AdminInterface.ts:84
#: src/pages/admin-overview/AdminOverviewPage.ts:61 #: src/pages/admin-overview/AdminOverviewPage.ts:61
#: src/pages/flows/FlowListPage.ts:28 #: src/pages/flows/FlowListPage.ts:29
#: src/pages/stages/StageListPage.ts:66 #: src/pages/stages/StageListPage.ts:66
msgid "Flows" msgid "Flows"
msgstr "Flows" msgstr "Flows"
#: src/pages/flows/FlowListPage.ts:31 #: src/pages/flows/FlowListPage.ts:32
msgid "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them." msgid "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them."
msgstr "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them." msgstr "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them."
@ -1546,7 +1585,7 @@ msgstr "Hide service-accounts"
#: src/pages/providers/saml/SAMLProviderForm.ts:176 #: src/pages/providers/saml/SAMLProviderForm.ts:176
#: src/pages/sources/ldap/LDAPSourceForm.ts:165 #: src/pages/sources/ldap/LDAPSourceForm.ts:165
#: src/pages/sources/ldap/LDAPSourceForm.ts:191 #: src/pages/sources/ldap/LDAPSourceForm.ts:191
#: src/pages/sources/plex/PlexSourceForm.ts:168 #: src/pages/sources/plex/PlexSourceForm.ts:121
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114 #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
#: src/pages/stages/identification/IdentificationStageForm.ts:83 #: src/pages/stages/identification/IdentificationStageForm.ts:83
#: src/pages/stages/password/PasswordStageForm.ts:84 #: src/pages/stages/password/PasswordStageForm.ts:84
@ -1567,7 +1606,7 @@ msgstr "ID"
msgid "Icon" msgid "Icon"
msgstr "Icon" msgstr "Icon"
#: src/pages/flows/FlowListPage.ts:46 #: src/pages/flows/FlowListPage.ts:47
#: src/pages/system-tasks/SystemTaskListPage.ts:54 #: src/pages/system-tasks/SystemTaskListPage.ts:54
#: src/pages/tokens/TokenListPage.ts:44 #: src/pages/tokens/TokenListPage.ts:44
#: src/pages/user-settings/tokens/UserTokenForm.ts:49 #: src/pages/user-settings/tokens/UserTokenForm.ts:49
@ -1600,12 +1639,12 @@ msgstr "If your authentik Instance is using a self-signed certificate, set this
msgid "Impersonate" msgid "Impersonate"
msgstr "Impersonate" msgstr "Impersonate"
#: src/pages/flows/FlowListPage.ts:122 #: src/pages/flows/FlowListPage.ts:123
#: src/pages/flows/FlowListPage.ts:130 #: src/pages/flows/FlowListPage.ts:131
msgid "Import" msgid "Import"
msgstr "Import" msgstr "Import"
#: src/pages/flows/FlowListPage.ts:125 #: src/pages/flows/FlowListPage.ts:126
msgid "Import Flow" msgid "Import Flow"
msgstr "Import Flow" msgstr "Import Flow"
@ -1716,7 +1755,7 @@ msgstr "Last login"
msgid "Last run" msgid "Last run"
msgstr "Last run" msgstr "Last run"
#: src/pages/outposts/OutpostHealth.ts:54 #: src/pages/outposts/OutpostHealth.ts:53
msgid "Last seen: {0}" msgid "Last seen: {0}"
msgstr "Last seen: {0}" msgstr "Last seen: {0}"
@ -1742,21 +1781,21 @@ msgid "Library"
msgstr "Library" msgstr "Library"
#: src/pages/sources/oauth/OAuthSourceForm.ts:147 #: src/pages/sources/oauth/OAuthSourceForm.ts:147
#: src/pages/sources/plex/PlexSourceForm.ts:121 #: src/pages/sources/plex/PlexSourceForm.ts:156
msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses" msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
msgstr "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses" msgstr "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
#: src/pages/sources/oauth/OAuthSourceForm.ts:153 #: src/pages/sources/oauth/OAuthSourceForm.ts:153
#: src/pages/sources/plex/PlexSourceForm.ts:127 #: src/pages/sources/plex/PlexSourceForm.ts:162
msgid "Link to a user with identical username address. Can have security implications when a username is used with another source." msgid "Link to a user with identical username address. Can have security implications when a username is used with another source."
msgstr "Link to a user with identical username address. Can have security implications when a username is used with another source." msgstr "Link to a user with identical username address. Can have security implications when a username is used with another source."
#: src/pages/sources/oauth/OAuthSourceForm.ts:144 #: src/pages/sources/oauth/OAuthSourceForm.ts:144
#: src/pages/sources/plex/PlexSourceForm.ts:118 #: src/pages/sources/plex/PlexSourceForm.ts:153
msgid "Link users on unique identifier" msgid "Link users on unique identifier"
msgstr "Link users on unique identifier" msgstr "Link users on unique identifier"
#: src/pages/sources/plex/PlexSourceForm.ts:173 #: src/pages/sources/plex/PlexSourceForm.ts:96
msgid "Load servers" msgid "Load servers"
msgstr "Load servers" msgstr "Load servers"
@ -1821,8 +1860,8 @@ msgstr "Loading"
#: src/pages/sources/oauth/OAuthSourceForm.ts:219 #: src/pages/sources/oauth/OAuthSourceForm.ts:219
#: src/pages/sources/oauth/OAuthSourceForm.ts:247 #: src/pages/sources/oauth/OAuthSourceForm.ts:247
#: src/pages/sources/oauth/OAuthSourceForm.ts:268 #: src/pages/sources/oauth/OAuthSourceForm.ts:268
#: src/pages/sources/plex/PlexSourceForm.ts:201 #: src/pages/sources/plex/PlexSourceForm.ts:206
#: src/pages/sources/plex/PlexSourceForm.ts:222 #: src/pages/sources/plex/PlexSourceForm.ts:227
#: src/pages/sources/saml/SAMLSourceForm.ts:124 #: src/pages/sources/saml/SAMLSourceForm.ts:124
#: src/pages/sources/saml/SAMLSourceForm.ts:238 #: src/pages/sources/saml/SAMLSourceForm.ts:238
#: src/pages/sources/saml/SAMLSourceForm.ts:259 #: src/pages/sources/saml/SAMLSourceForm.ts:259
@ -1961,7 +2000,7 @@ msgstr "My Applications"
#: src/pages/events/TransportListPage.ts:46 #: src/pages/events/TransportListPage.ts:46
#: src/pages/flows/BoundStagesList.ts:39 #: src/pages/flows/BoundStagesList.ts:39
#: src/pages/flows/FlowForm.ts:86 #: src/pages/flows/FlowForm.ts:86
#: src/pages/flows/FlowListPage.ts:47 #: src/pages/flows/FlowListPage.ts:48
#: src/pages/groups/GroupForm.ts:58 #: src/pages/groups/GroupForm.ts:58
#: src/pages/groups/GroupListPage.ts:45 #: src/pages/groups/GroupListPage.ts:45
#: src/pages/groups/MemberSelectModal.ts:45 #: src/pages/groups/MemberSelectModal.ts:45
@ -1970,7 +2009,7 @@ msgstr "My Applications"
#: src/pages/outposts/ServiceConnectionDockerForm.ts:51 #: src/pages/outposts/ServiceConnectionDockerForm.ts:51
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts:52 #: src/pages/outposts/ServiceConnectionKubernetesForm.ts:52
#: src/pages/outposts/ServiceConnectionListPage.ts:53 #: src/pages/outposts/ServiceConnectionListPage.ts:53
#: src/pages/policies/PolicyListPage.ts:56 #: src/pages/policies/PolicyListPage.ts:57
#: src/pages/policies/dummy/DummyPolicyForm.ts:54 #: src/pages/policies/dummy/DummyPolicyForm.ts:54
#: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:55 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:55
#: src/pages/policies/expiry/ExpiryPolicyForm.ts:54 #: src/pages/policies/expiry/ExpiryPolicyForm.ts:54
@ -1997,7 +2036,7 @@ msgstr "My Applications"
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:108 #: src/pages/sources/oauth/OAuthSourceForm.ts:108
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:64
#: src/pages/sources/plex/PlexSourceForm.ts:93 #: src/pages/sources/plex/PlexSourceForm.ts:128
#: src/pages/sources/plex/PlexSourceViewPage.ts:63 #: src/pages/sources/plex/PlexSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:52 #: src/pages/sources/saml/SAMLSourceForm.ts:52
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66 #: src/pages/sources/saml/SAMLSourceViewPage.ts:66
@ -2359,15 +2398,15 @@ msgstr "Please enter your password"
#: src/interfaces/AdminInterface.ts:74 #: src/interfaces/AdminInterface.ts:74
#: src/pages/admin-overview/AdminOverviewPage.ts:56 #: src/pages/admin-overview/AdminOverviewPage.ts:56
#: src/pages/flows/FlowListPage.ts:50 #: src/pages/flows/FlowListPage.ts:51
#: src/pages/policies/PolicyListPage.ts:38 #: src/pages/policies/PolicyListPage.ts:39
msgid "Policies" msgid "Policies"
msgstr "Policies" msgstr "Policies"
#: src/pages/policies/PolicyBindingForm.ts:108 #: src/pages/policies/PolicyBindingForm.ts:108
#: src/pages/policies/PolicyBindingForm.ts:117 #: src/pages/policies/PolicyBindingForm.ts:117
#: src/pages/policies/PolicyBindingForm.ts:148 #: src/pages/policies/PolicyBindingForm.ts:148
#: src/pages/policies/PolicyListPage.ts:108 #: src/pages/policies/PolicyListPage.ts:109
msgid "Policy" msgid "Policy"
msgstr "Policy" msgstr "Policy"
@ -2492,7 +2531,7 @@ msgstr "Protocol Settings"
#: src/pages/providers/proxy/ProxyProviderForm.ts:123 #: src/pages/providers/proxy/ProxyProviderForm.ts:123
#: src/pages/providers/saml/SAMLProviderForm.ts:77 #: src/pages/providers/saml/SAMLProviderForm.ts:77
#: src/pages/sources/oauth/OAuthSourceForm.ts:163 #: src/pages/sources/oauth/OAuthSourceForm.ts:163
#: src/pages/sources/plex/PlexSourceForm.ts:137 #: src/pages/sources/plex/PlexSourceForm.ts:172
#: src/pages/sources/saml/SAMLSourceForm.ts:74 #: src/pages/sources/saml/SAMLSourceForm.ts:74
msgid "Protocol settings" msgid "Protocol settings"
msgstr "Protocol settings" msgstr "Protocol settings"
@ -2623,7 +2662,7 @@ msgid "Regular expressions for which authentication is not required. Each new li
msgstr "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." msgstr "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression."
#: src/pages/applications/ApplicationViewPage.ts:62 #: src/pages/applications/ApplicationViewPage.ts:62
#: src/pages/flows/FlowViewPage.ts:64 #: src/pages/flows/FlowViewPage.ts:56
msgid "Related" msgid "Related"
msgstr "Related" msgstr "Related"
@ -2800,7 +2839,7 @@ msgstr "Select users to add"
msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data." msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
msgstr "Select which scopes can be used by the client. The client stil has to specify the scope to access the data." msgstr "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
#: src/pages/sources/plex/PlexSourceForm.ts:167 #: src/pages/sources/plex/PlexSourceForm.ts:120
msgid "Select which server a user has to be a member of to be allowed to authenticate." msgid "Select which server a user has to be a member of to be allowed to authenticate."
msgstr "Select which server a user has to be a member of to be allowed to authenticate." msgstr "Select which server a user has to be a member of to be allowed to authenticate."
@ -2940,7 +2979,7 @@ msgstr "Skip path regex"
#: src/pages/flows/FlowForm.ts:99 #: src/pages/flows/FlowForm.ts:99
#: src/pages/sources/ldap/LDAPSourceForm.ts:58 #: src/pages/sources/ldap/LDAPSourceForm.ts:58
#: src/pages/sources/oauth/OAuthSourceForm.ts:114 #: src/pages/sources/oauth/OAuthSourceForm.ts:114
#: src/pages/sources/plex/PlexSourceForm.ts:99 #: src/pages/sources/plex/PlexSourceForm.ts:134
#: src/pages/sources/saml/SAMLSourceForm.ts:58 #: src/pages/sources/saml/SAMLSourceForm.ts:58
msgid "Slug" msgid "Slug"
msgstr "Slug" msgstr "Slug"
@ -3017,7 +3056,7 @@ msgid "Stage-specific settings"
msgstr "Stage-specific settings" msgstr "Stage-specific settings"
#: src/interfaces/AdminInterface.ts:87 #: src/interfaces/AdminInterface.ts:87
#: src/pages/flows/FlowListPage.ts:49 #: src/pages/flows/FlowListPage.ts:50
#: src/pages/stages/StageListPage.ts:44 #: src/pages/stages/StageListPage.ts:44
#: src/pages/stages/prompt/PromptListPage.ts:50 #: src/pages/stages/prompt/PromptListPage.ts:50
msgid "Stages" msgid "Stages"
@ -3081,6 +3120,14 @@ msgstr "Subject-alt name"
msgid "Successful" msgid "Successful"
msgstr "Successful" msgstr "Successful"
#: src/pages/flows/FlowListPage.ts:136
msgid "Successfully cleared flow cache"
msgstr "Successfully cleared flow cache"
#: src/pages/policies/PolicyListPage.ts:155
msgid "Successfully cleared policy cache"
msgstr "Successfully cleared policy cache"
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:63 #: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:63
msgid "Successfully copied TOTP Config." msgid "Successfully copied TOTP Config."
msgstr "Successfully copied TOTP Config." msgstr "Successfully copied TOTP Config."
@ -3405,14 +3452,14 @@ msgid "Template"
msgstr "Template" msgstr "Template"
#: src/pages/events/TransportListPage.ts:62 #: src/pages/events/TransportListPage.ts:62
#: src/pages/policies/PolicyListPage.ts:95 #: src/pages/policies/PolicyListPage.ts:96
#: src/pages/policies/PolicyListPage.ts:103 #: src/pages/policies/PolicyListPage.ts:104
#: src/pages/property-mappings/PropertyMappingListPage.ts:84 #: src/pages/property-mappings/PropertyMappingListPage.ts:84
#: src/pages/property-mappings/PropertyMappingListPage.ts:92 #: src/pages/property-mappings/PropertyMappingListPage.ts:92
msgid "Test" msgid "Test"
msgstr "Test" msgstr "Test"
#: src/pages/policies/PolicyListPage.ts:98 #: src/pages/policies/PolicyListPage.ts:99
msgid "Test Policy" msgid "Test Policy"
msgstr "Test Policy" msgstr "Test Policy"
@ -3429,8 +3476,8 @@ msgid "The URL \"{0}\" was not found."
msgstr "The URL \"{0}\" was not found." msgstr "The URL \"{0}\" was not found."
#: src/pages/providers/proxy/ProxyProviderForm.ts:131 #: src/pages/providers/proxy/ProxyProviderForm.ts:131
msgid "The external URL you'll access the application at" msgid "The external URL you'll access the application at. Include any non-standard port."
msgstr "The external URL you'll access the application at" msgstr "The external URL you'll access the application at. Include any non-standard port."
#: src/pages/policies/dummy/DummyPolicyForm.ts:88 #: src/pages/policies/dummy/DummyPolicyForm.ts:88
msgid "The policy takes a random time to execute. This controls the minimum time it will take." msgid "The policy takes a random time to execute. This controls the minimum time it will take."
@ -3564,7 +3611,7 @@ msgstr "Transports"
#: src/pages/flows/BoundStagesList.ts:40 #: src/pages/flows/BoundStagesList.ts:40
#: src/pages/outposts/OutpostForm.ts:58 #: src/pages/outposts/OutpostForm.ts:58
#: src/pages/outposts/ServiceConnectionListPage.ts:54 #: src/pages/outposts/ServiceConnectionListPage.ts:54
#: src/pages/policies/PolicyListPage.ts:57 #: src/pages/policies/PolicyListPage.ts:58
#: src/pages/property-mappings/PropertyMappingListPage.ts:55 #: src/pages/property-mappings/PropertyMappingListPage.ts:55
#: src/pages/providers/ProviderListPage.ts:55 #: src/pages/providers/ProviderListPage.ts:55
#: src/pages/sources/SourcesListPage.ts:53 #: src/pages/sources/SourcesListPage.ts:53
@ -3640,7 +3687,7 @@ msgstr "Up-to-date!"
#: src/pages/events/TransportListPage.ts:66 #: src/pages/events/TransportListPage.ts:66
#: src/pages/flows/BoundStagesList.ts:53 #: src/pages/flows/BoundStagesList.ts:53
#: src/pages/flows/BoundStagesList.ts:71 #: src/pages/flows/BoundStagesList.ts:71
#: src/pages/flows/FlowListPage.ts:66 #: src/pages/flows/FlowListPage.ts:67
#: src/pages/groups/GroupListPage.ts:61 #: src/pages/groups/GroupListPage.ts:61
#: src/pages/outposts/OutpostListPage.ts:67 #: src/pages/outposts/OutpostListPage.ts:67
#: src/pages/outposts/ServiceConnectionListPage.ts:76 #: src/pages/outposts/ServiceConnectionListPage.ts:76
@ -3648,7 +3695,7 @@ msgstr "Up-to-date!"
#: src/pages/policies/BoundPoliciesList.ts:88 #: src/pages/policies/BoundPoliciesList.ts:88
#: src/pages/policies/BoundPoliciesList.ts:103 #: src/pages/policies/BoundPoliciesList.ts:103
#: src/pages/policies/BoundPoliciesList.ts:129 #: src/pages/policies/BoundPoliciesList.ts:129
#: src/pages/policies/PolicyListPage.ts:77 #: src/pages/policies/PolicyListPage.ts:78
#: src/pages/property-mappings/PropertyMappingListPage.ts:66 #: src/pages/property-mappings/PropertyMappingListPage.ts:66
#: src/pages/providers/ProviderListPage.ts:74 #: src/pages/providers/ProviderListPage.ts:74
#: src/pages/providers/ldap/LDAPProviderViewPage.ts:93 #: src/pages/providers/ldap/LDAPProviderViewPage.ts:93
@ -3686,7 +3733,7 @@ msgstr "Update Binding"
msgid "Update Certificate-Key Pair" msgid "Update Certificate-Key Pair"
msgstr "Update Certificate-Key Pair" msgstr "Update Certificate-Key Pair"
#: src/pages/flows/FlowListPage.ts:69 #: src/pages/flows/FlowListPage.ts:70
msgid "Update Flow" msgid "Update Flow"
msgstr "Update Flow" msgstr "Update Flow"
@ -3764,7 +3811,7 @@ msgstr "Update details"
#: src/pages/flows/BoundStagesList.ts:56 #: src/pages/flows/BoundStagesList.ts:56
#: src/pages/outposts/ServiceConnectionListPage.ts:79 #: src/pages/outposts/ServiceConnectionListPage.ts:79
#: src/pages/policies/BoundPoliciesList.ts:71 #: src/pages/policies/BoundPoliciesList.ts:71
#: src/pages/policies/PolicyListPage.ts:80 #: src/pages/policies/PolicyListPage.ts:81
#: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:77 #: src/pages/providers/ProviderListPage.ts:77
#: src/pages/sources/SourcesListPage.ts:73 #: src/pages/sources/SourcesListPage.ts:73
@ -3798,12 +3845,12 @@ msgid "Use global settings"
msgstr "Use global settings" msgstr "Use global settings"
#: src/pages/sources/oauth/OAuthSourceForm.ts:150 #: src/pages/sources/oauth/OAuthSourceForm.ts:150
#: src/pages/sources/plex/PlexSourceForm.ts:124 #: src/pages/sources/plex/PlexSourceForm.ts:159
msgid "Use the user's email address, but deny enrollment when the email address already exists." msgid "Use the user's email address, but deny enrollment when the email address already exists."
msgstr "Use the user's email address, but deny enrollment when the email address already exists." msgstr "Use the user's email address, but deny enrollment when the email address already exists."
#: src/pages/sources/oauth/OAuthSourceForm.ts:156 #: src/pages/sources/oauth/OAuthSourceForm.ts:156
#: src/pages/sources/plex/PlexSourceForm.ts:130 #: src/pages/sources/plex/PlexSourceForm.ts:165
msgid "Use the user's username, but deny enrollment when the username already exists." msgid "Use the user's username, but deny enrollment when the username already exists."
msgstr "Use the user's username, but deny enrollment when the username already exists." msgstr "Use the user's username, but deny enrollment when the username already exists."
@ -3852,7 +3899,7 @@ msgid "User fields"
msgstr "User fields" msgstr "User fields"
#: src/pages/sources/oauth/OAuthSourceForm.ts:139 #: src/pages/sources/oauth/OAuthSourceForm.ts:139
#: src/pages/sources/plex/PlexSourceForm.ts:113 #: src/pages/sources/plex/PlexSourceForm.ts:148
msgid "User matching mode" msgid "User matching mode"
msgstr "User matching mode" msgstr "User matching mode"
@ -3913,8 +3960,8 @@ msgid "Users added to this group will be superusers."
msgstr "Users added to this group will be superusers." msgstr "Users added to this group will be superusers."
#: src/pages/providers/ldap/LDAPProviderForm.ts:86 #: src/pages/providers/ldap/LDAPProviderForm.ts:86
msgid "Users in the selected group can do search queries." msgid "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
msgstr "Users in the selected group can do search queries." msgstr "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
#: src/pages/events/EventInfo.ts:108 #: src/pages/events/EventInfo.ts:108
msgid "Using flow" msgid "Using flow"
@ -3956,7 +4003,7 @@ msgstr "Verify the user's email address by sending them a one-time-link. Can als
msgid "Version" msgid "Version"
msgstr "Version" msgstr "Version"
#: src/pages/outposts/OutpostHealth.ts:60 #: src/pages/outposts/OutpostHealth.ts:59
msgid "Version: {0}" msgid "Version: {0}"
msgstr "Version: {0}" msgstr "Version: {0}"
@ -3985,7 +4032,7 @@ msgstr "Wait (min)"
msgid "Warning" msgid "Warning"
msgstr "Warning" msgstr "Warning"
#: src/pages/policies/PolicyListPage.ts:71 #: src/pages/policies/PolicyListPage.ts:72
msgid "Warning: Policy is not assigned." msgid "Warning: Policy is not assigned."
msgstr "Warning: Policy is not assigned." msgstr "Warning: Policy is not assigned."
@ -4122,7 +4169,7 @@ msgstr "{0} is available!"
msgid "{0} unread" msgid "{0} unread"
msgstr "{0} unread" msgstr "{0} unread"
#: src/pages/outposts/OutpostHealth.ts:59 #: src/pages/outposts/OutpostHealth.ts:58
msgid "{0}, should be {1}" msgid "{0}, should be {1}"
msgstr "{0}, should be {1}" msgstr "{0}, should be {1}"

View File

@ -144,7 +144,7 @@ msgstr ""
msgid "Allow IDP-initiated logins" msgid "Allow IDP-initiated logins"
msgstr "" msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:150 #: src/pages/sources/plex/PlexSourceForm.ts:103
msgid "Allow friends to authenticate via Plex, even if you don't share any servers" msgid "Allow friends to authenticate via Plex, even if you don't share any servers"
msgstr "" msgstr ""
@ -152,7 +152,7 @@ msgstr ""
msgid "Allow up to N occurrences in the HIBP database." msgid "Allow up to N occurrences in the HIBP database."
msgstr "" msgstr ""
#: src/pages/policies/PolicyListPage.ts:41 #: src/pages/policies/PolicyListPage.ts:42
msgid "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages." msgid "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages."
msgstr "" msgstr ""
@ -164,7 +164,7 @@ msgstr ""
msgid "Allowed count" msgid "Allowed count"
msgstr "" msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:155 #: src/pages/sources/plex/PlexSourceForm.ts:108
msgid "Allowed servers" msgid "Allowed servers"
msgstr "" msgstr ""
@ -218,6 +218,18 @@ msgstr ""
msgid "Apps with most usage" msgid "Apps with most usage"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:146
msgid ""
"Are you sure you want to clear the flow cache?\n"
"This will cause all flows to be re-evaluated on their next usage."
msgstr ""
#: src/pages/policies/PolicyListPage.ts:165
msgid ""
"Are you sure you want to clear the policy cache?\n"
"This will cause all policies to be re-evaluated on their next usage."
msgstr ""
#: src/elements/forms/DeleteForm.ts:69 #: src/elements/forms/DeleteForm.ts:69
msgid "Are you sure you want to delete {0} {objName} ?" msgid "Are you sure you want to delete {0} {objName} ?"
msgstr "" msgstr ""
@ -250,7 +262,7 @@ msgstr ""
msgid "Assigned to application" msgid "Assigned to application"
msgstr "" msgstr ""
#: src/pages/policies/PolicyListPage.ts:68 #: src/pages/policies/PolicyListPage.ts:69
msgid "Assigned to {0} objects." msgid "Assigned to {0} objects."
msgstr "" msgstr ""
@ -282,7 +294,7 @@ msgid "Authentication"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:231 #: src/pages/sources/oauth/OAuthSourceForm.ts:231
#: src/pages/sources/plex/PlexSourceForm.ts:185 #: src/pages/sources/plex/PlexSourceForm.ts:190
#: src/pages/sources/saml/SAMLSourceForm.ts:243 #: src/pages/sources/saml/SAMLSourceForm.ts:243
msgid "Authentication flow" msgid "Authentication flow"
msgstr "" msgstr ""
@ -528,6 +540,21 @@ msgstr ""
msgid "Checks the value from the policy request against several rules, mostly used to ensure password strength." msgid "Checks the value from the policy request against several rules, mostly used to ensure password strength."
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:143
msgid "Clear Flow cache"
msgstr ""
#: src/pages/policies/PolicyListPage.ts:162
msgid "Clear Policy cache"
msgstr ""
#: src/pages/flows/FlowListPage.ts:138
#: src/pages/flows/FlowListPage.ts:150
#: src/pages/policies/PolicyListPage.ts:157
#: src/pages/policies/PolicyListPage.ts:169
msgid "Clear cache"
msgstr ""
#: src/elements/forms/HorizontalFormElement.ts:82 #: src/elements/forms/HorizontalFormElement.ts:82
msgid "Click to change value" msgid "Click to change value"
msgstr "" msgstr ""
@ -538,7 +565,7 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99
#: src/pages/sources/plex/PlexSourceForm.ts:141 #: src/pages/sources/plex/PlexSourceForm.ts:176
msgid "Client ID" msgid "Client ID"
msgstr "" msgstr ""
@ -724,8 +751,8 @@ msgstr ""
#: src/pages/flows/BoundStagesList.ts:119 #: src/pages/flows/BoundStagesList.ts:119
#: src/pages/flows/BoundStagesList.ts:146 #: src/pages/flows/BoundStagesList.ts:146
#: src/pages/flows/BoundStagesList.ts:167 #: src/pages/flows/BoundStagesList.ts:167
#: src/pages/flows/FlowListPage.ts:109 #: src/pages/flows/FlowListPage.ts:110
#: src/pages/flows/FlowListPage.ts:117 #: src/pages/flows/FlowListPage.ts:118
#: src/pages/groups/GroupListPage.ts:90 #: src/pages/groups/GroupListPage.ts:90
#: src/pages/groups/GroupListPage.ts:98 #: src/pages/groups/GroupListPage.ts:98
#: src/pages/outposts/OutpostListPage.ts:101 #: src/pages/outposts/OutpostListPage.ts:101
@ -735,8 +762,8 @@ msgstr ""
#: src/pages/policies/BoundPoliciesList.ts:162 #: src/pages/policies/BoundPoliciesList.ts:162
#: src/pages/policies/BoundPoliciesList.ts:189 #: src/pages/policies/BoundPoliciesList.ts:189
#: src/pages/policies/BoundPoliciesList.ts:210 #: src/pages/policies/BoundPoliciesList.ts:210
#: src/pages/policies/PolicyListPage.ts:124 #: src/pages/policies/PolicyListPage.ts:125
#: src/pages/policies/PolicyListPage.ts:133 #: src/pages/policies/PolicyListPage.ts:134
#: src/pages/property-mappings/PropertyMappingListPage.ts:113 #: src/pages/property-mappings/PropertyMappingListPage.ts:113
#: src/pages/property-mappings/PropertyMappingListPage.ts:122 #: src/pages/property-mappings/PropertyMappingListPage.ts:122
#: src/pages/providers/ProviderListPage.ts:108 #: src/pages/providers/ProviderListPage.ts:108
@ -776,7 +803,7 @@ msgstr ""
msgid "Create Certificate-Key Pair" msgid "Create Certificate-Key Pair"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:112 #: src/pages/flows/FlowListPage.ts:113
msgid "Create Flow" msgid "Create Flow"
msgstr "" msgstr ""
@ -838,7 +865,7 @@ msgstr ""
#: src/pages/flows/BoundStagesList.ts:149 #: src/pages/flows/BoundStagesList.ts:149
#: src/pages/outposts/ServiceConnectionListPage.ts:122 #: src/pages/outposts/ServiceConnectionListPage.ts:122
#: src/pages/policies/BoundPoliciesList.ts:192 #: src/pages/policies/BoundPoliciesList.ts:192
#: src/pages/policies/PolicyListPage.ts:136 #: src/pages/policies/PolicyListPage.ts:137
#: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:120 #: src/pages/providers/ProviderListPage.ts:120
#: src/pages/sources/SourcesListPage.ts:126 #: src/pages/sources/SourcesListPage.ts:126
@ -890,11 +917,11 @@ msgstr ""
#: src/pages/crypto/CertificateKeyPairListPage.ts:86 #: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82 #: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86 #: src/pages/events/TransportListPage.ts:86
#: src/pages/flows/FlowListPage.ts:86 #: src/pages/flows/FlowListPage.ts:87
#: src/pages/groups/GroupListPage.ts:81 #: src/pages/groups/GroupListPage.ts:81
#: src/pages/outposts/OutpostListPage.ts:87 #: src/pages/outposts/OutpostListPage.ts:87
#: src/pages/outposts/ServiceConnectionListPage.ts:101 #: src/pages/outposts/ServiceConnectionListPage.ts:101
#: src/pages/policies/PolicyListPage.ts:115 #: src/pages/policies/PolicyListPage.ts:116
#: src/pages/property-mappings/PropertyMappingListPage.ts:104 #: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:99 #: src/pages/providers/ProviderListPage.ts:99
#: src/pages/sources/SourcesListPage.ts:95 #: src/pages/sources/SourcesListPage.ts:95
@ -963,7 +990,7 @@ msgid "Designates whether this user should be treated as active. Unselect this i
msgstr "" msgstr ""
#: src/pages/flows/FlowForm.ts:119 #: src/pages/flows/FlowForm.ts:119
#: src/pages/flows/FlowListPage.ts:48 #: src/pages/flows/FlowListPage.ts:49
msgid "Designation" msgid "Designation"
msgstr "" msgstr ""
@ -1045,11 +1072,11 @@ msgstr ""
#: src/pages/crypto/CertificateKeyPairListPage.ts:74 #: src/pages/crypto/CertificateKeyPairListPage.ts:74
#: src/pages/events/RuleListPage.ts:70 #: src/pages/events/RuleListPage.ts:70
#: src/pages/events/TransportListPage.ts:74 #: src/pages/events/TransportListPage.ts:74
#: src/pages/flows/FlowListPage.ts:74 #: src/pages/flows/FlowListPage.ts:75
#: src/pages/groups/GroupListPage.ts:69 #: src/pages/groups/GroupListPage.ts:69
#: src/pages/outposts/OutpostListPage.ts:75 #: src/pages/outposts/OutpostListPage.ts:75
#: src/pages/outposts/ServiceConnectionListPage.ts:89 #: src/pages/outposts/ServiceConnectionListPage.ts:89
#: src/pages/policies/PolicyListPage.ts:90 #: src/pages/policies/PolicyListPage.ts:91
#: src/pages/property-mappings/PropertyMappingListPage.ts:79 #: src/pages/property-mappings/PropertyMappingListPage.ts:79
#: src/pages/providers/ProviderListPage.ts:87 #: src/pages/providers/ProviderListPage.ts:87
#: src/pages/providers/ldap/LDAPProviderViewPage.ts:103 #: src/pages/providers/ldap/LDAPProviderViewPage.ts:103
@ -1144,7 +1171,7 @@ msgstr ""
#: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/policies/PolicyBindingForm.ts:199
#: src/pages/sources/ldap/LDAPSourceForm.ts:67 #: src/pages/sources/ldap/LDAPSourceForm.ts:67
#: src/pages/sources/oauth/OAuthSourceForm.ts:134 #: src/pages/sources/oauth/OAuthSourceForm.ts:134
#: src/pages/sources/plex/PlexSourceForm.ts:108 #: src/pages/sources/plex/PlexSourceForm.ts:143
#: src/pages/sources/saml/SAMLSourceForm.ts:67 #: src/pages/sources/saml/SAMLSourceForm.ts:67
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr ""
@ -1154,7 +1181,7 @@ msgid "Enrollment"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:252 #: src/pages/sources/oauth/OAuthSourceForm.ts:252
#: src/pages/sources/plex/PlexSourceForm.ts:206 #: src/pages/sources/plex/PlexSourceForm.ts:211
#: src/pages/sources/saml/SAMLSourceForm.ts:264 #: src/pages/sources/saml/SAMLSourceForm.ts:264
#: src/pages/stages/identification/IdentificationStageForm.ts:104 #: src/pages/stages/identification/IdentificationStageForm.ts:104
msgid "Enrollment flow" msgid "Enrollment flow"
@ -1221,12 +1248,12 @@ msgstr ""
msgid "Exception" msgid "Exception"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:98 #: src/pages/flows/FlowListPage.ts:99
#: src/pages/flows/FlowViewPage.ts:83 #: src/pages/flows/FlowViewPage.ts:75
msgid "Execute" msgid "Execute"
msgstr "" msgstr ""
#: src/pages/flows/FlowViewPage.ts:69 #: src/pages/flows/FlowViewPage.ts:61
msgid "Execute flow" msgid "Execute flow"
msgstr "" msgstr ""
@ -1273,7 +1300,7 @@ msgstr ""
msgid "Explicit Consent" msgid "Explicit Consent"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:101 #: src/pages/flows/FlowListPage.ts:102
msgid "Export" msgid "Export"
msgstr "" msgstr ""
@ -1312,6 +1339,14 @@ msgstr ""
msgid "Failed sources" msgid "Failed sources"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:137
msgid "Failed to delete flow cache"
msgstr ""
#: src/pages/policies/PolicyListPage.ts:156
msgid "Failed to delete policy cache"
msgstr ""
#: src/elements/forms/DeleteForm.ts:46 #: src/elements/forms/DeleteForm.ts:46
msgid "Failed to delete {0}: {1}" msgid "Failed to delete {0}: {1}"
msgstr "" msgstr ""
@ -1354,7 +1389,7 @@ msgid "Fields a user can identify themselves with. If no fields are selected, th
msgstr "" msgstr ""
#: src/pages/flows/FlowImportForm.ts:34 #: src/pages/flows/FlowImportForm.ts:34
#: src/pages/flows/FlowListPage.ts:79 #: src/pages/flows/FlowListPage.ts:80
msgid "Flow" msgid "Flow"
msgstr "" msgstr ""
@ -1363,19 +1398,19 @@ msgid "Flow Overview"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:227 #: src/pages/sources/oauth/OAuthSourceForm.ts:227
#: src/pages/sources/plex/PlexSourceForm.ts:181 #: src/pages/sources/plex/PlexSourceForm.ts:186
#: src/pages/sources/saml/SAMLSourceForm.ts:218 #: src/pages/sources/saml/SAMLSourceForm.ts:218
msgid "Flow settings" msgid "Flow settings"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:249 #: src/pages/sources/oauth/OAuthSourceForm.ts:249
#: src/pages/sources/plex/PlexSourceForm.ts:203 #: src/pages/sources/plex/PlexSourceForm.ts:208
#: src/pages/sources/saml/SAMLSourceForm.ts:261 #: src/pages/sources/saml/SAMLSourceForm.ts:261
msgid "Flow to use when authenticating existing users." msgid "Flow to use when authenticating existing users."
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:270 #: src/pages/sources/oauth/OAuthSourceForm.ts:270
#: src/pages/sources/plex/PlexSourceForm.ts:224 #: src/pages/sources/plex/PlexSourceForm.ts:229
#: src/pages/sources/saml/SAMLSourceForm.ts:282 #: src/pages/sources/saml/SAMLSourceForm.ts:282
msgid "Flow to use when enrolling new users." msgid "Flow to use when enrolling new users."
msgstr "" msgstr ""
@ -1407,12 +1442,12 @@ msgstr ""
#: src/interfaces/AdminInterface.ts:82 #: src/interfaces/AdminInterface.ts:82
#: src/interfaces/AdminInterface.ts:84 #: src/interfaces/AdminInterface.ts:84
#: src/pages/admin-overview/AdminOverviewPage.ts:61 #: src/pages/admin-overview/AdminOverviewPage.ts:61
#: src/pages/flows/FlowListPage.ts:28 #: src/pages/flows/FlowListPage.ts:29
#: src/pages/stages/StageListPage.ts:66 #: src/pages/stages/StageListPage.ts:66
msgid "Flows" msgid "Flows"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:31 #: src/pages/flows/FlowListPage.ts:32
msgid "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them." msgid "Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them."
msgstr "" msgstr ""
@ -1542,7 +1577,7 @@ msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:176 #: src/pages/providers/saml/SAMLProviderForm.ts:176
#: src/pages/sources/ldap/LDAPSourceForm.ts:165 #: src/pages/sources/ldap/LDAPSourceForm.ts:165
#: src/pages/sources/ldap/LDAPSourceForm.ts:191 #: src/pages/sources/ldap/LDAPSourceForm.ts:191
#: src/pages/sources/plex/PlexSourceForm.ts:168 #: src/pages/sources/plex/PlexSourceForm.ts:121
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114 #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
#: src/pages/stages/identification/IdentificationStageForm.ts:83 #: src/pages/stages/identification/IdentificationStageForm.ts:83
#: src/pages/stages/password/PasswordStageForm.ts:84 #: src/pages/stages/password/PasswordStageForm.ts:84
@ -1563,7 +1598,7 @@ msgstr ""
msgid "Icon" msgid "Icon"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:46 #: src/pages/flows/FlowListPage.ts:47
#: src/pages/system-tasks/SystemTaskListPage.ts:54 #: src/pages/system-tasks/SystemTaskListPage.ts:54
#: src/pages/tokens/TokenListPage.ts:44 #: src/pages/tokens/TokenListPage.ts:44
#: src/pages/user-settings/tokens/UserTokenForm.ts:49 #: src/pages/user-settings/tokens/UserTokenForm.ts:49
@ -1596,12 +1631,12 @@ msgstr ""
msgid "Impersonate" msgid "Impersonate"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:122 #: src/pages/flows/FlowListPage.ts:123
#: src/pages/flows/FlowListPage.ts:130 #: src/pages/flows/FlowListPage.ts:131
msgid "Import" msgid "Import"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:125 #: src/pages/flows/FlowListPage.ts:126
msgid "Import Flow" msgid "Import Flow"
msgstr "" msgstr ""
@ -1712,7 +1747,7 @@ msgstr ""
msgid "Last run" msgid "Last run"
msgstr "" msgstr ""
#: src/pages/outposts/OutpostHealth.ts:54 #: src/pages/outposts/OutpostHealth.ts:53
msgid "Last seen: {0}" msgid "Last seen: {0}"
msgstr "" msgstr ""
@ -1738,21 +1773,21 @@ msgid "Library"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:147 #: src/pages/sources/oauth/OAuthSourceForm.ts:147
#: src/pages/sources/plex/PlexSourceForm.ts:121 #: src/pages/sources/plex/PlexSourceForm.ts:156
msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses" msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:153 #: src/pages/sources/oauth/OAuthSourceForm.ts:153
#: src/pages/sources/plex/PlexSourceForm.ts:127 #: src/pages/sources/plex/PlexSourceForm.ts:162
msgid "Link to a user with identical username address. Can have security implications when a username is used with another source." msgid "Link to a user with identical username address. Can have security implications when a username is used with another source."
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:144 #: src/pages/sources/oauth/OAuthSourceForm.ts:144
#: src/pages/sources/plex/PlexSourceForm.ts:118 #: src/pages/sources/plex/PlexSourceForm.ts:153
msgid "Link users on unique identifier" msgid "Link users on unique identifier"
msgstr "" msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:173 #: src/pages/sources/plex/PlexSourceForm.ts:96
msgid "Load servers" msgid "Load servers"
msgstr "" msgstr ""
@ -1817,8 +1852,8 @@ msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:219 #: src/pages/sources/oauth/OAuthSourceForm.ts:219
#: src/pages/sources/oauth/OAuthSourceForm.ts:247 #: src/pages/sources/oauth/OAuthSourceForm.ts:247
#: src/pages/sources/oauth/OAuthSourceForm.ts:268 #: src/pages/sources/oauth/OAuthSourceForm.ts:268
#: src/pages/sources/plex/PlexSourceForm.ts:201 #: src/pages/sources/plex/PlexSourceForm.ts:206
#: src/pages/sources/plex/PlexSourceForm.ts:222 #: src/pages/sources/plex/PlexSourceForm.ts:227
#: src/pages/sources/saml/SAMLSourceForm.ts:124 #: src/pages/sources/saml/SAMLSourceForm.ts:124
#: src/pages/sources/saml/SAMLSourceForm.ts:238 #: src/pages/sources/saml/SAMLSourceForm.ts:238
#: src/pages/sources/saml/SAMLSourceForm.ts:259 #: src/pages/sources/saml/SAMLSourceForm.ts:259
@ -1957,7 +1992,7 @@ msgstr ""
#: src/pages/events/TransportListPage.ts:46 #: src/pages/events/TransportListPage.ts:46
#: src/pages/flows/BoundStagesList.ts:39 #: src/pages/flows/BoundStagesList.ts:39
#: src/pages/flows/FlowForm.ts:86 #: src/pages/flows/FlowForm.ts:86
#: src/pages/flows/FlowListPage.ts:47 #: src/pages/flows/FlowListPage.ts:48
#: src/pages/groups/GroupForm.ts:58 #: src/pages/groups/GroupForm.ts:58
#: src/pages/groups/GroupListPage.ts:45 #: src/pages/groups/GroupListPage.ts:45
#: src/pages/groups/MemberSelectModal.ts:45 #: src/pages/groups/MemberSelectModal.ts:45
@ -1966,7 +2001,7 @@ msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts:51 #: src/pages/outposts/ServiceConnectionDockerForm.ts:51
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts:52 #: src/pages/outposts/ServiceConnectionKubernetesForm.ts:52
#: src/pages/outposts/ServiceConnectionListPage.ts:53 #: src/pages/outposts/ServiceConnectionListPage.ts:53
#: src/pages/policies/PolicyListPage.ts:56 #: src/pages/policies/PolicyListPage.ts:57
#: src/pages/policies/dummy/DummyPolicyForm.ts:54 #: src/pages/policies/dummy/DummyPolicyForm.ts:54
#: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:55 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:55
#: src/pages/policies/expiry/ExpiryPolicyForm.ts:54 #: src/pages/policies/expiry/ExpiryPolicyForm.ts:54
@ -1993,7 +2028,7 @@ msgstr ""
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:108 #: src/pages/sources/oauth/OAuthSourceForm.ts:108
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:64
#: src/pages/sources/plex/PlexSourceForm.ts:93 #: src/pages/sources/plex/PlexSourceForm.ts:128
#: src/pages/sources/plex/PlexSourceViewPage.ts:63 #: src/pages/sources/plex/PlexSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:52 #: src/pages/sources/saml/SAMLSourceForm.ts:52
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66 #: src/pages/sources/saml/SAMLSourceViewPage.ts:66
@ -2355,15 +2390,15 @@ msgstr ""
#: src/interfaces/AdminInterface.ts:74 #: src/interfaces/AdminInterface.ts:74
#: src/pages/admin-overview/AdminOverviewPage.ts:56 #: src/pages/admin-overview/AdminOverviewPage.ts:56
#: src/pages/flows/FlowListPage.ts:50 #: src/pages/flows/FlowListPage.ts:51
#: src/pages/policies/PolicyListPage.ts:38 #: src/pages/policies/PolicyListPage.ts:39
msgid "Policies" msgid "Policies"
msgstr "" msgstr ""
#: src/pages/policies/PolicyBindingForm.ts:108 #: src/pages/policies/PolicyBindingForm.ts:108
#: src/pages/policies/PolicyBindingForm.ts:117 #: src/pages/policies/PolicyBindingForm.ts:117
#: src/pages/policies/PolicyBindingForm.ts:148 #: src/pages/policies/PolicyBindingForm.ts:148
#: src/pages/policies/PolicyListPage.ts:108 #: src/pages/policies/PolicyListPage.ts:109
msgid "Policy" msgid "Policy"
msgstr "" msgstr ""
@ -2488,7 +2523,7 @@ msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts:123 #: src/pages/providers/proxy/ProxyProviderForm.ts:123
#: src/pages/providers/saml/SAMLProviderForm.ts:77 #: src/pages/providers/saml/SAMLProviderForm.ts:77
#: src/pages/sources/oauth/OAuthSourceForm.ts:163 #: src/pages/sources/oauth/OAuthSourceForm.ts:163
#: src/pages/sources/plex/PlexSourceForm.ts:137 #: src/pages/sources/plex/PlexSourceForm.ts:172
#: src/pages/sources/saml/SAMLSourceForm.ts:74 #: src/pages/sources/saml/SAMLSourceForm.ts:74
msgid "Protocol settings" msgid "Protocol settings"
msgstr "" msgstr ""
@ -2619,7 +2654,7 @@ msgid "Regular expressions for which authentication is not required. Each new li
msgstr "" msgstr ""
#: src/pages/applications/ApplicationViewPage.ts:62 #: src/pages/applications/ApplicationViewPage.ts:62
#: src/pages/flows/FlowViewPage.ts:64 #: src/pages/flows/FlowViewPage.ts:56
msgid "Related" msgid "Related"
msgstr "" msgstr ""
@ -2796,7 +2831,7 @@ msgstr ""
msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data." msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
msgstr "" msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:167 #: src/pages/sources/plex/PlexSourceForm.ts:120
msgid "Select which server a user has to be a member of to be allowed to authenticate." msgid "Select which server a user has to be a member of to be allowed to authenticate."
msgstr "" msgstr ""
@ -2936,7 +2971,7 @@ msgstr ""
#: src/pages/flows/FlowForm.ts:99 #: src/pages/flows/FlowForm.ts:99
#: src/pages/sources/ldap/LDAPSourceForm.ts:58 #: src/pages/sources/ldap/LDAPSourceForm.ts:58
#: src/pages/sources/oauth/OAuthSourceForm.ts:114 #: src/pages/sources/oauth/OAuthSourceForm.ts:114
#: src/pages/sources/plex/PlexSourceForm.ts:99 #: src/pages/sources/plex/PlexSourceForm.ts:134
#: src/pages/sources/saml/SAMLSourceForm.ts:58 #: src/pages/sources/saml/SAMLSourceForm.ts:58
msgid "Slug" msgid "Slug"
msgstr "" msgstr ""
@ -3013,7 +3048,7 @@ msgid "Stage-specific settings"
msgstr "" msgstr ""
#: src/interfaces/AdminInterface.ts:87 #: src/interfaces/AdminInterface.ts:87
#: src/pages/flows/FlowListPage.ts:49 #: src/pages/flows/FlowListPage.ts:50
#: src/pages/stages/StageListPage.ts:44 #: src/pages/stages/StageListPage.ts:44
#: src/pages/stages/prompt/PromptListPage.ts:50 #: src/pages/stages/prompt/PromptListPage.ts:50
msgid "Stages" msgid "Stages"
@ -3077,6 +3112,14 @@ msgstr ""
msgid "Successful" msgid "Successful"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:136
msgid "Successfully cleared flow cache"
msgstr ""
#: src/pages/policies/PolicyListPage.ts:155
msgid "Successfully cleared policy cache"
msgstr ""
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:63 #: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:63
msgid "Successfully copied TOTP Config." msgid "Successfully copied TOTP Config."
msgstr "" msgstr ""
@ -3401,14 +3444,14 @@ msgid "Template"
msgstr "" msgstr ""
#: src/pages/events/TransportListPage.ts:62 #: src/pages/events/TransportListPage.ts:62
#: src/pages/policies/PolicyListPage.ts:95 #: src/pages/policies/PolicyListPage.ts:96
#: src/pages/policies/PolicyListPage.ts:103 #: src/pages/policies/PolicyListPage.ts:104
#: src/pages/property-mappings/PropertyMappingListPage.ts:84 #: src/pages/property-mappings/PropertyMappingListPage.ts:84
#: src/pages/property-mappings/PropertyMappingListPage.ts:92 #: src/pages/property-mappings/PropertyMappingListPage.ts:92
msgid "Test" msgid "Test"
msgstr "" msgstr ""
#: src/pages/policies/PolicyListPage.ts:98 #: src/pages/policies/PolicyListPage.ts:99
msgid "Test Policy" msgid "Test Policy"
msgstr "" msgstr ""
@ -3425,7 +3468,7 @@ msgid "The URL \"{0}\" was not found."
msgstr "" msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts:131 #: src/pages/providers/proxy/ProxyProviderForm.ts:131
msgid "The external URL you'll access the application at" msgid "The external URL you'll access the application at. Include any non-standard port."
msgstr "" msgstr ""
#: src/pages/policies/dummy/DummyPolicyForm.ts:88 #: src/pages/policies/dummy/DummyPolicyForm.ts:88
@ -3556,7 +3599,7 @@ msgstr ""
#: src/pages/flows/BoundStagesList.ts:40 #: src/pages/flows/BoundStagesList.ts:40
#: src/pages/outposts/OutpostForm.ts:58 #: src/pages/outposts/OutpostForm.ts:58
#: src/pages/outposts/ServiceConnectionListPage.ts:54 #: src/pages/outposts/ServiceConnectionListPage.ts:54
#: src/pages/policies/PolicyListPage.ts:57 #: src/pages/policies/PolicyListPage.ts:58
#: src/pages/property-mappings/PropertyMappingListPage.ts:55 #: src/pages/property-mappings/PropertyMappingListPage.ts:55
#: src/pages/providers/ProviderListPage.ts:55 #: src/pages/providers/ProviderListPage.ts:55
#: src/pages/sources/SourcesListPage.ts:53 #: src/pages/sources/SourcesListPage.ts:53
@ -3632,7 +3675,7 @@ msgstr ""
#: src/pages/events/TransportListPage.ts:66 #: src/pages/events/TransportListPage.ts:66
#: src/pages/flows/BoundStagesList.ts:53 #: src/pages/flows/BoundStagesList.ts:53
#: src/pages/flows/BoundStagesList.ts:71 #: src/pages/flows/BoundStagesList.ts:71
#: src/pages/flows/FlowListPage.ts:66 #: src/pages/flows/FlowListPage.ts:67
#: src/pages/groups/GroupListPage.ts:61 #: src/pages/groups/GroupListPage.ts:61
#: src/pages/outposts/OutpostListPage.ts:67 #: src/pages/outposts/OutpostListPage.ts:67
#: src/pages/outposts/ServiceConnectionListPage.ts:76 #: src/pages/outposts/ServiceConnectionListPage.ts:76
@ -3640,7 +3683,7 @@ msgstr ""
#: src/pages/policies/BoundPoliciesList.ts:88 #: src/pages/policies/BoundPoliciesList.ts:88
#: src/pages/policies/BoundPoliciesList.ts:103 #: src/pages/policies/BoundPoliciesList.ts:103
#: src/pages/policies/BoundPoliciesList.ts:129 #: src/pages/policies/BoundPoliciesList.ts:129
#: src/pages/policies/PolicyListPage.ts:77 #: src/pages/policies/PolicyListPage.ts:78
#: src/pages/property-mappings/PropertyMappingListPage.ts:66 #: src/pages/property-mappings/PropertyMappingListPage.ts:66
#: src/pages/providers/ProviderListPage.ts:74 #: src/pages/providers/ProviderListPage.ts:74
#: src/pages/providers/ldap/LDAPProviderViewPage.ts:93 #: src/pages/providers/ldap/LDAPProviderViewPage.ts:93
@ -3678,7 +3721,7 @@ msgstr ""
msgid "Update Certificate-Key Pair" msgid "Update Certificate-Key Pair"
msgstr "" msgstr ""
#: src/pages/flows/FlowListPage.ts:69 #: src/pages/flows/FlowListPage.ts:70
msgid "Update Flow" msgid "Update Flow"
msgstr "" msgstr ""
@ -3756,7 +3799,7 @@ msgstr ""
#: src/pages/flows/BoundStagesList.ts:56 #: src/pages/flows/BoundStagesList.ts:56
#: src/pages/outposts/ServiceConnectionListPage.ts:79 #: src/pages/outposts/ServiceConnectionListPage.ts:79
#: src/pages/policies/BoundPoliciesList.ts:71 #: src/pages/policies/BoundPoliciesList.ts:71
#: src/pages/policies/PolicyListPage.ts:80 #: src/pages/policies/PolicyListPage.ts:81
#: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:77 #: src/pages/providers/ProviderListPage.ts:77
#: src/pages/sources/SourcesListPage.ts:73 #: src/pages/sources/SourcesListPage.ts:73
@ -3790,12 +3833,12 @@ msgid "Use global settings"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:150 #: src/pages/sources/oauth/OAuthSourceForm.ts:150
#: src/pages/sources/plex/PlexSourceForm.ts:124 #: src/pages/sources/plex/PlexSourceForm.ts:159
msgid "Use the user's email address, but deny enrollment when the email address already exists." msgid "Use the user's email address, but deny enrollment when the email address already exists."
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:156 #: src/pages/sources/oauth/OAuthSourceForm.ts:156
#: src/pages/sources/plex/PlexSourceForm.ts:130 #: src/pages/sources/plex/PlexSourceForm.ts:165
msgid "Use the user's username, but deny enrollment when the username already exists." msgid "Use the user's username, but deny enrollment when the username already exists."
msgstr "" msgstr ""
@ -3844,7 +3887,7 @@ msgid "User fields"
msgstr "" msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:139 #: src/pages/sources/oauth/OAuthSourceForm.ts:139
#: src/pages/sources/plex/PlexSourceForm.ts:113 #: src/pages/sources/plex/PlexSourceForm.ts:148
msgid "User matching mode" msgid "User matching mode"
msgstr "" msgstr ""
@ -3905,7 +3948,7 @@ msgid "Users added to this group will be superusers."
msgstr "" msgstr ""
#: src/pages/providers/ldap/LDAPProviderForm.ts:86 #: src/pages/providers/ldap/LDAPProviderForm.ts:86
msgid "Users in the selected group can do search queries." msgid "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
msgstr "" msgstr ""
#: src/pages/events/EventInfo.ts:108 #: src/pages/events/EventInfo.ts:108
@ -3948,7 +3991,7 @@ msgstr ""
msgid "Version" msgid "Version"
msgstr "" msgstr ""
#: src/pages/outposts/OutpostHealth.ts:60 #: src/pages/outposts/OutpostHealth.ts:59
msgid "Version: {0}" msgid "Version: {0}"
msgstr "" msgstr ""
@ -3977,7 +4020,7 @@ msgstr ""
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#: src/pages/policies/PolicyListPage.ts:71 #: src/pages/policies/PolicyListPage.ts:72
msgid "Warning: Policy is not assigned." msgid "Warning: Policy is not assigned."
msgstr "" msgstr ""
@ -4112,7 +4155,7 @@ msgstr ""
msgid "{0} unread" msgid "{0} unread"
msgstr "" msgstr ""
#: src/pages/outposts/OutpostHealth.ts:59 #: src/pages/outposts/OutpostHealth.ts:58
msgid "{0}, should be {1}" msgid "{0}, should be {1}"
msgstr "" msgstr ""

View File

@ -6,6 +6,7 @@ import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/SpinnerButton"; import "../../elements/buttons/SpinnerButton";
import "../../elements/forms/DeleteForm"; import "../../elements/forms/DeleteForm";
import "../../elements/forms/ModalForm"; import "../../elements/forms/ModalForm";
import "../../elements/forms/ConfirmationForm";
import "./FlowForm"; import "./FlowForm";
import "./FlowImportForm"; import "./FlowImportForm";
import { TableColumn } from "../../elements/table/Table"; import { TableColumn } from "../../elements/table/Table";
@ -68,7 +69,7 @@ export class FlowListPage extends TablePage<Flow> {
<span slot="header"> <span slot="header">
${t`Update Flow`} ${t`Update Flow`}
</span> </span>
<ak-flow-form slot="form" .instancePk=${item.pk}> <ak-flow-form slot="form" .instancePk=${item.slug}>
</ak-flow-form> </ak-flow-form>
<button slot="trigger" class="pf-c-button pf-m-secondary"> <button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`} ${t`Edit`}
@ -132,6 +133,24 @@ export class FlowListPage extends TablePage<Flow> {
</button> </button>
</ak-forms-modal> </ak-forms-modal>
${super.renderToolbar()} ${super.renderToolbar()}
`; <ak-forms-confirm
successMessage=${t`Successfully cleared flow cache`}
errorMessage=${t`Failed to delete flow cache`}
action=${t`Clear cache`}
.onConfirm=${() => {
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesCacheClear();
}}>
<span slot="header">
${t`Clear Flow cache`}
</span>
<p slot="body">
${t`Are you sure you want to clear the flow cache?
This will cause all flows to be re-evaluated on their next usage.`}
</p>
<button slot="trigger" class="pf-c-button pf-m-secondary" type="button">
${t`Clear cache`}
</button>
<div slot="modal"></div>
</ak-forms-confirm>`;
} }
} }

View File

@ -8,6 +8,7 @@ import "../../elements/buttons/SpinnerButton";
import "../../elements/forms/DeleteForm"; import "../../elements/forms/DeleteForm";
import "../../elements/forms/ModalForm"; import "../../elements/forms/ModalForm";
import "../../elements/forms/ProxyForm"; import "../../elements/forms/ProxyForm";
import "../../elements/forms/ConfirmationForm";
import "./PolicyTestForm"; import "./PolicyTestForm";
import { TableColumn } from "../../elements/table/Table"; import { TableColumn } from "../../elements/table/Table";
import { until } from "lit-html/directives/until"; import { until } from "lit-html/directives/until";
@ -150,7 +151,26 @@ export class PolicyListPage extends TablePage<Policy> {
}), html`<ak-spinner></ak-spinner>`)} }), html`<ak-spinner></ak-spinner>`)}
</ul> </ul>
</ak-dropdown> </ak-dropdown>
${super.renderToolbar()}`; ${super.renderToolbar()}
<ak-forms-confirm
successMessage=${t`Successfully cleared policy cache`}
errorMessage=${t`Failed to delete policy cache`}
action=${t`Clear cache`}
.onConfirm=${() => {
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCacheClear();
}}>
<span slot="header">
${t`Clear Policy cache`}
</span>
<p slot="body">
${t`Are you sure you want to clear the policy cache?
This will cause all policies to be re-evaluated on their next usage.`}
</p>
<button slot="trigger" class="pf-c-button pf-m-secondary" type="button">
${t`Clear cache`}
</button>
<div slot="modal"></div>
</ak-forms-confirm>`;
} }
} }

View File

@ -73,7 +73,7 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
<ak-proxy-form <ak-proxy-form
slot="form" slot="form"
.args=${{ .args=${{
"mappingUUID": item.pk "instancePk": item.pk
}} }}
type=${ifDefined(item.component)}> type=${ifDefined(item.component)}>
</ak-proxy-form> </ak-proxy-form>

View File

@ -75,7 +75,7 @@ export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
}); });
}), html`<option>${t`Loading...`}</option>`)} }), html`<option>${t`Loading...`}</option>`)}
</select> </select>
<p class="pf-c-form__helper-text">${t`Users in the selected group can do search queries.`}</p> <p class="pf-c-form__helper-text">${t`Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed.`}</p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-group .expanded=${true}> <ak-form-group .expanded=${true}>

View File

@ -125,7 +125,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
?required=${true} ?required=${true}
name="externalHost"> name="externalHost">
<input type="text" value="${ifDefined(this.instance?.externalHost)}" class="pf-c-form-control" required> <input type="text" value="${ifDefined(this.instance?.externalHost)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`The external URL you'll access the application at`}</p> <p class="pf-c-form__helper-text">${t`The external URL you'll access the application at. Include any non-standard port.`}</p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="forwardAuthMode"> <ak-form-element-horizontal name="forwardAuthMode">
<div class="pf-c-check"> <div class="pf-c-check">

View File

@ -46,7 +46,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
} }
send = (data: PlexSource): Promise<PlexSource> => { send = (data: PlexSource): Promise<PlexSource> => {
data.plexToken = this.plexToken; data.plexToken = this.plexToken || "";
if (this.instance?.slug) { if (this.instance?.slug) {
return new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({ return new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({
slug: this.instance.slug, slug: this.instance.slug,

View File

@ -22,6 +22,7 @@ postgresql:
user: postgres user: postgres
log_level: debug log_level: debug
secret_key: "A long key you can generate with `pwgen 40 1` for example"
``` ```
Afterwards, you can start authentik by running `./manage.py runserver`. Generally speaking, authentik is a Django application. Afterwards, you can start authentik by running `./manage.py runserver`. Generally speaking, authentik is a Django application.

View File

@ -12,11 +12,11 @@ This installation method is for test-setups and small-scale productive setups.
## Preparation ## Preparation
Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.4/docker-compose.yml). Place it in a directory of your choice. Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version/2021.5.4/docker-compose.yml). Place it in a directory of your choice.
To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env` To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env`
To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.5.1 >> .env` To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.5.4 >> .env`
If this is a fresh authentik install run the following commands to generate a password: If this is a fresh authentik install run the following commands to generate a password:

View File

@ -16,7 +16,18 @@ You can configure under which base DN the information should be available. For t
Users are available under `ou=users,<base DN>` and groups under `ou=groups,<base DN>`. Users are available under `ou=users,<base DN>` and groups under `ou=groups,<base DN>`.
You can bind using the DN `cn=<username>,ou=users,<base DN>`. You can bind using the DN `cn=<username>,ou=users,<base DN>`, or using the following ldapsearch command for example:
```
ldapsearch \
-x \ # Only simple binds are currently supported
-h *ip* \
-p 3389 \
-D 'cn=*user*,ou=users,DC=ldap,DC=goauthentik,DC=io' \ # Bind user and password
-w '*password*' \
-b 'ou=users,DC=ldap,DC=goauthentik,DC=io' \ # The search base
'(objectClass=user)'
```
The following fields are currently sent for users: The following fields are currently sent for users:

View File

@ -11,7 +11,7 @@ version: "3.5"
services: services:
authentik_proxy: authentik_proxy:
image: beryju/authentik-proxy:2021.5.1 image: ghcr.io/goauthentik/proxy:2021.5.4
ports: ports:
- 4180:4180 - 4180:4180
- 4443:4443 - 4443:4443
@ -19,4 +19,13 @@ services:
AUTHENTIK_HOST: https://your-authentik.tld AUTHENTIK_HOST: https://your-authentik.tld
AUTHENTIK_INSECURE: "false" AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: token-generated-by-authentik AUTHENTIK_TOKEN: token-generated-by-authentik
# Or, for the LDAP Outpost
authentik_proxy:
image: ghcr.io/goauthentik/ldap:2021.5.4
ports:
- 389:3389
environment:
AUTHENTIK_HOST: https://your-authentik.tld
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: token-generated-by-authentik
``` ```

View File

@ -14,7 +14,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
name: authentik-outpost-api name: authentik-outpost-api
stringData: stringData:
authentik_host: "__AUTHENTIK_URL__" authentik_host: "__AUTHENTIK_URL__"
@ -29,7 +29,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
name: authentik-outpost name: authentik-outpost
spec: spec:
ports: ports:
@ -54,7 +54,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
name: authentik-outpost name: authentik-outpost
spec: spec:
selector: selector:
@ -62,14 +62,14 @@ spec:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
template: template:
metadata: metadata:
labels: labels:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
spec: spec:
containers: containers:
- env: - env:
@ -88,7 +88,7 @@ spec:
secretKeyRef: secretKeyRef:
key: authentik_host_insecure key: authentik_host_insecure
name: authentik-outpost-api name: authentik-outpost-api
image: beryju/authentik-proxy:2021.5.1 image: ghcr.io/goauthentik/proxy:2021.5.4
name: proxy name: proxy
ports: ports:
- containerPort: 4180 - containerPort: 4180
@ -110,7 +110,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1 app.kubernetes.io/version: 2021.5.4
name: authentik-outpost name: authentik-outpost
spec: spec:
rules: rules:

View File

@ -15,6 +15,14 @@ Additionally, you can set `additionalHeaders` on groups or users to set addition
If you enable *Set HTTP-Basic Authentication* option, the HTTP Authorization header is being set. If you enable *Set HTTP-Basic Authentication* option, the HTTP Authorization header is being set.
# HTTPS
The outpost listens on both 4180 for HTTP and 4443 for HTTPS.
:::warning
If your upstream host is HTTPS, and you're not using forward auth, you need to access the outpost over HTTPS too.
:::
# Forward auth # Forward auth
To use forward auth instead of proxying, you have to change a couple of settings. In the Proxy Provider, make sure to enable `Enable forward-auth mode` on the provider. To use forward auth instead of proxying, you have to change a couple of settings. In the Proxy Provider, make sure to enable `Enable forward-auth mode` on the provider.
@ -35,8 +43,10 @@ import TabItem from '@theme/TabItem';
``` ```
location /akprox { location /akprox {
proxy_pass http://*ip of your outpost*:4180; proxy_pass http://*ip of your outpost*:4180;
proxy_set_header X-Forwarded-Host $http_host;
error_page 401 = @akprox_signin; error_page 401 = @akprox_signin;
proxy_set_header X-Forwarded-Host $http_host;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
} }
location @akprox_signin { location @akprox_signin {
@ -157,7 +167,7 @@ services:
- '--entrypoints.https.address=:443' - '--entrypoints.https.address=:443'
authentik_proxy: authentik_proxy:
image: beryju/authentik-proxy:2021.4.4 image: ghcr.io/goauthentik/proxy:2021.5.1
ports: ports:
- 4180:4180 - 4180:4180
- 4443:4443 - 4443:4443

View File

@ -51,7 +51,7 @@ This release does not introduce any new requirements.
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-0.14/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`. Download the docker-compose file for 0.14 from  [here](https://raw.githubusercontent.com/goauthentik/authentik/version-0.14/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`.
### Kubernetes ### Kubernetes

View File

@ -60,7 +60,7 @@ This release does not introduce any new requirements.
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.1/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`. Download the docker-compose file for 2021.1 from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.1/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`.
### Kubernetes ### Kubernetes

View File

@ -124,7 +124,7 @@ The integrations affected are:
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.2/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`. Download the docker-compose file for 2021.2 from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.2/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`.
### Kubernetes ### Kubernetes

View File

@ -87,7 +87,7 @@ This release does not introduce any new requirements.
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.3/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`. Download the docker-compose file for 2021.3 from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.3/docker-compose.yml). Afterwards, simply run `docker-compose up -d` and then the standard upgrade command of `docker-compose run --rm server migrate`.
### Kubernetes ### Kubernetes

View File

@ -133,7 +133,7 @@ This release does not introduce any new requirements.
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.4/docker-compose.yml). Afterwards, simply run `docker-compose up -d`. Download the docker-compose file for 2021.4 from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.4/docker-compose.yml). Afterwards, simply run `docker-compose up -d`.
### Kubernetes ### Kubernetes

View File

@ -24,7 +24,7 @@ This feature is still in technical preview, so please report any Bugs you run in
- Docker images for ARM - Docker images for ARM
Docker images are now built for amd64, arm64, arm v7 and arm v8. Docker images are now built for amd64 and arm64.
- Reduced setup complexity - Reduced setup complexity
@ -58,13 +58,35 @@ This feature is still in technical preview, so please report any Bugs you run in
- Add single-use flag for invitations to delete token after use. - Add single-use flag for invitations to delete token after use.
- Fix sidebar not collapsible on mobile. - Fix sidebar not collapsible on mobile.
## Fixed in 2021.5.2
- core: fix application's slug field not being set to unique
- flows: fix error when using cancel flow
- lib: Fix config loading of secrets from files (#887)
- lib: fix parsing of remote IP header when behind multiple reverse proxies
- lifecycle: check if group of docker socket exists
- lifecycle: fix error when worker is not running as root
- outposts: fix error when controller loads from cache but cache has expired
- outposts: fix missing default for OutpostState.for_channel
- outposts: fix reload notification not working due to wrong ID being cached
- outposts/ldap: fix AUTHENTIK_INSECURE not being respected for API client during bind
- outposts/proxy: fix error redeeming code when using non-standard ports
- outposts/proxy: fix insecure TLS Skip
- providers/ldap: use username instead of name for user dn (#883)
- providers/proxy: connect ingress to https instead of http
- root: only load debug secret key when debug is enabled
- web: fix chunks overwriting each other
- web/admin: add notice for LDAP Provider's group selection
- web/admin: fix PropertyMappings not loading correctly
- website/docs: add example ldapsearch command
## Upgrading ## Upgrading
This release does not introduce any new requirements. This release does not introduce any new requirements.
### docker-compose ### docker-compose
Download the latest docker-compose file from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.5/docker-compose.yml). Afterwards, simply run `docker-compose up -d`. Download the docker-compose file for 2021.5 from [here](https://raw.githubusercontent.com/goauthentik/authentik/version-2021.5/docker-compose.yml). Afterwards, simply run `docker-compose up -d`.
:::warning :::warning
The public port of the compose stack has been changed from 443 to 9000 and 9443 to prevent port contention. The public port of the compose stack has been changed from 443 to 9000 and 9443 to prevent port contention.