Compare commits

...

93 Commits

Author SHA1 Message Date
e20bb7d636 release: 2021.4.3 2021-04-20 09:15:07 +02:00
e9abc25b92 website/docs: prepare changelog for 2021.4.3
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 21:08:10 +02:00
dc930c0cdf website/docs: manually set slug so release note URLs don't break
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 21:05:19 +02:00
464a1c0536 api: make 401 messages clearer
closes #755

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 20:46:57 +02:00
837d2f6fab outpost: use tools from docker (#758)
* outpost: replace golang.org/x/lint with golangci-lint

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* outpost: use swagger generator from docker

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* outpost: don't use tty for swagger gen

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* outposts: revert docker-swagger gen

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 20:43:13 +02:00
8f00d73512 website: fix main site not rendering because <BrowserOnly>
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 19:23:26 +02:00
b75feab709 outposts: don't run outpost_controller when no service connection is set
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 19:23:26 +02:00
9c8433ec4d fix(docs/grafana): Fix a silly (#757) 2021-04-19 19:22:23 +02:00
ef080900a4 feat(docs/grafana): Add role mapping info (#756)
* feat(docs/grafana): Add role mapping info

* feat(docs/grafana): More info on role mappings
2021-04-19 19:07:09 +02:00
10b45a8dea api: fix 401 responses which should be 403s
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 19:03:00 +02:00
c43ac1f704 api: mount outposts under outposts/instances to match flows
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 18:51:12 +02:00
14d702450a core: add parameter to output property mapping test formatted
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 18:32:36 +02:00
0a1a2a035e web/admin: fix *Test Forms not having a default for codemirrors
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 18:25:16 +02:00
ace777ebbe website: re-sort releases, add outposts to terminology
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 17:25:26 +02:00
8a6879afa5 core: add superuser_full_list to applications list, shows all applications when superuser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 16:07:30 +02:00
fdc7f14056 core: fix Tokens being created with incorrect intent by default
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 15:43:16 +02:00
8be80aaf9d api: fix CSRF error when using POST/PATCH/PUT in API Browser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 15:31:32 +02:00
e476f2dda2 website: bump deps
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-19 09:28:48 +02:00
5d48cfab14 build(deps): bump @docusaurus/core in /website (#753) 2021-04-19 08:22:35 +02:00
1f22f0e7bb build(deps): bump chart.js from 3.1.0 to 3.1.1 in /web (#751) 2021-04-19 08:22:02 +02:00
ce082ead5e providers/oauth2: add unittests for authorize and token views
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 21:05:49 +02:00
dd2cd09637 web/admin: fix undefined being shown when viewing application
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 19:04:10 +02:00
828fe07fca website: dynamically load rapidoc to prevent react errors
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 17:58:36 +02:00
a074ea70e9 website/docs-dev: add initial translation docs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 17:31:15 +02:00
84ce2c1df2 website: separate development docs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 17:25:58 +02:00
8628595590 website: add API Browser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 17:15:19 +02:00
7b8e5c4272 root: auto-migrate on startup, lock database using pg_advisory_lock
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 14:47:50 +02:00
caa5dc1d14 web/admin: improve default selection for property-mappings
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 14:21:05 +02:00
f328b21e89 providers/oauth2: Set CORS Headers for token endpoint, check Origin header against redirect URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-18 14:20:50 +02:00
52abd959eb sources/oauth: save null instead of empty string for sources without configurable URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 21:15:06 +02:00
a0cd17a257 docs: add troubleshooting for permission issues
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 20:09:03 +02:00
32c5bf04b8 *: fix linting errors
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 20:08:49 +02:00
766c4873a0 web/admin: add ability to add users to a group whilst creating a group
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:56:49 +02:00
240136154b web/admin: fix default for codemirror
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:37:13 +02:00
78dd7b0341 web/admin: fix group member table order
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:36:55 +02:00
0021a93952 web/admin: fix non-matching provider type being selected when creating an OAuth Source
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:17:08 +02:00
67240fb9ad *: add model_name to TypeCreate API to pass to forms
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:12:00 +02:00
4add0bbe86 web/admin: fix provider type resetting when changing provider type
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:06:56 +02:00
d2dd7d1366 sources/oauth: fix redirect loop for source with non-configurable URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 19:06:12 +02:00
476e57daa2 Merge branch 'version-2021.4'
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

# Conflicts:
#	docker-compose.yml
#	website/docs/installation/kubernetes.md
2021-04-17 16:01:35 +02:00
4eb8a0dcd1 docs: prepare changelog for 2021.4.2
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 15:29:55 +02:00
60615c9f3e release: 2021.4.2 2021-04-17 15:26:59 +02:00
b5b8573d87 core: fix propertymapping API returning invalid value for components
closes #746

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:05 +02:00
2e44c1cdfc sources/ldap: improve error handling during sync
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:05 +02:00
31909a4d78 outpost: fix outpost deps
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:05 +02:00
4a444e667a root: base Websocket message storage on Base not fallback
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:05 +02:00
f67b57e369 flows: fix linting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
6be19962d2 outposts: bump go version
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
262a9fa2a0 flows: annotate flows executor 404 error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
e8ba159756 root: fix setting of EMAIL_USE_TLS and EMAIL_USE_SSL
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
0b03d66a2f outposts: fix errors when creating multiple outposts
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
7c858c9626 web/admin: fix errors in user profile when non-superuser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
71b6839d03 flows: include configure_flow in stages API
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
ada49c077a web/admin: fix error when user doesn't have permissions to read source
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:04 +02:00
7880c7fb98 helm: make storage class, size and mode configurable
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:03 +02:00
2b48ba4103 sources/oauth: fix resolution of sources' provider type
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:03 +02:00
5e67f68f2b core: improve messaging when creating a recovery link for a user when no recovery flow exists
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:03 +02:00
1992b89154 sources/oauth: fix error when creating an oauth source which has fixed URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:01:03 +02:00
9ab2088ab7 helm: turn off monitoring by default
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:00:27 +02:00
a9d0d96418 root: add restart: unless-stopped to compose
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 12:00:27 +02:00
c476503594 web: fix background-color on router outlet on light mode
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 11:59:37 +02:00
de74f3ec1f core: fix propertymapping API returning invalid value for components
closes #746

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 11:50:28 +02:00
ce98255607 sources/ldap: improve error handling during sync
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 11:29:51 +02:00
53b9e5b93f outpost: fix outpost deps
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 11:16:40 +02:00
7aeb390eac docs: add note for minimum values.yaml file for k8s install
closes #745

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-17 11:06:21 +02:00
5df9ad63cf root: base Websocket message storage on Base not fallback
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 23:46:03 +02:00
e4400476a2 flows: fix linting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 23:15:06 +02:00
ef3c01ec34 outposts: bump go version
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 23:01:10 +02:00
b136d3bc69 flows: annotate flows executor 404 error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 22:56:44 +02:00
c34fcc73dc root: fix setting of EMAIL_USE_TLS and EMAIL_USE_SSL
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 22:44:42 +02:00
11b09c4ebd outposts: fix errors when creating multiple outposts
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 22:43:35 +02:00
e32070ddeb web/admin: fix errors in user profile when non-superuser
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 17:24:58 +02:00
33a8cea007 flows: include configure_flow in stages API
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 17:19:48 +02:00
d01fd7cdb7 web/admin: fix error when user doesn't have permissions to read source
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 17:06:06 +02:00
1770e42cbf sources/oauth: add login with plex support
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 17:05:35 +02:00
2fed739be7 helm: make storage class, size and mode configurable
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 12:31:55 +02:00
aa820b2b4d website: fix enrollment for keycloak
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 12:23:46 +02:00
582d2eb5eb sources/oauth: fix resolution of sources' provider type
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 11:29:23 +02:00
c5e2635903 core: improve messaging when creating a recovery link for a user when no recovery flow exists
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 10:09:46 +02:00
cfe0a7a694 sources/oauth: fix error when creating an oauth source which has fixed URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 09:49:25 +02:00
c579540473 helm: turn off monitoring by default
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 09:20:17 +02:00
35f2b06611 build(deps): bump boto3 from 1.17.52 to 1.17.53 (#742)
Bumps [boto3](https://github.com/boto/boto3) from 1.17.52 to 1.17.53.
- [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.52...1.17.53)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-16 09:07:17 +02:00
9c4f025d71 build(deps): bump @types/codemirror from 0.0.108 to 0.0.109 in /web (#743)
Bumps [@types/codemirror](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/codemirror) from 0.0.108 to 0.0.109.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/codemirror)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-16 09:07:06 +02:00
d8b8e8a5a3 root: add restart: unless-stopped to compose
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-16 09:03:58 +02:00
ec34c3eb75 website: fix azure ad application proxy on comparison
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 20:59:14 +02:00
0554c94c53 docs: add notes for openssl
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 17:33:25 +02:00
19a663a645 root: fix healthcheck part in docker-compose
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 17:28:38 +02:00
e72881b2a9 root: fix healthcheck part in docker-compose
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 17:20:14 +02:00
4452ff171e docs: add Explanation what containers do what
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 16:12:55 +02:00
39bdc3a9a9 website: fix enrollment for keycloack
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 13:12:50 +02:00
33bb6edf8c web: fix background-color on router outlet on light mode
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 11:31:06 +02:00
2eb18ff5e6 root: fix expired discord invite
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-15 10:54:43 +02:00
aeb1b5e8f2 build(deps): bump boto3 from 1.17.51 to 1.17.52 (#736) 2021-04-15 09:16:09 +02:00
130 changed files with 6635 additions and 5814 deletions

View File

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

View File

@ -18,11 +18,11 @@ jobs:
- name: Building Docker Image
run: docker build
--no-cache
-t beryju/authentik:2021.4.1
-t beryju/authentik:2021.4.3
-t beryju/authentik:latest
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/authentik:2021.4.1
run: docker push beryju/authentik:2021.4.3
- name: Push Docker Container to Registry (latest)
run: docker push beryju/authentik:latest
build-proxy:
@ -48,11 +48,11 @@ jobs:
cd outpost/
docker build \
--no-cache \
-t beryju/authentik-proxy:2021.4.1 \
-t beryju/authentik-proxy:2021.4.3 \
-t beryju/authentik-proxy:latest \
-f proxy.Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/authentik-proxy:2021.4.1
run: docker push beryju/authentik-proxy:2021.4.3
- name: Push Docker Container to Registry (latest)
run: docker push beryju/authentik-proxy:latest
build-static:
@ -72,11 +72,11 @@ jobs:
cd web/
docker build \
--no-cache \
-t beryju/authentik-static:2021.4.1 \
-t beryju/authentik-static:2021.4.3 \
-t beryju/authentik-static:latest \
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/authentik-static:2021.4.1
run: docker push beryju/authentik-static:2021.4.3
- name: Push Docker Container to Registry (latest)
run: docker push beryju/authentik-static:latest
test-release:
@ -110,5 +110,5 @@ jobs:
SENTRY_PROJECT: authentik
SENTRY_URL: https://sentry.beryju.org
with:
tagName: 2021.4.1
tagName: 2021.4.3
environment: beryjuorg-prod

122
Pipfile.lock generated
View File

@ -116,18 +116,18 @@
},
"boto3": {
"hashes": [
"sha256:73bcd04f6f919e7f8acc27c9d83dab5aee22225fe624c028b2e1c7feaf771098",
"sha256:c45e7d3aef8965ae1b42c9855c31ded19fbb38cfad0a34cc37dc880ded3672c2"
"sha256:1d26f6e7ae3c940cb07119077ac42485dcf99164350da0ab50d0f5ad345800cd",
"sha256:3bf3305571f3c8b738a53e9e7dcff59137dffe94670046c084a17f9fa4599ff3"
],
"index": "pypi",
"version": "==1.17.51"
"version": "==1.17.53"
},
"botocore": {
"hashes": [
"sha256:ae45ea7451513373666b7571064c173d649e61fd3e8f413f0e1f1f9db26b3513",
"sha256:c853d6c2321e2f2328282c7d49d7b1a06201826ba0e7049c6975ab5f22927ea8"
"sha256:d5e70d17b91c9b5867be7d6de0caa7dde9ed789bed62f03ea9b60718dc9350bf",
"sha256:e303500c4e80f6a706602da53daa6f751cfa8f491665c99a24ee732ab6321573"
],
"version": "==1.20.51"
"version": "==1.20.53"
},
"cachetools": {
"hashes": [
@ -437,10 +437,10 @@
},
"google-auth": {
"hashes": [
"sha256:186fe2564634d67fbbb64f3daf8bc8c9cecbb2a7f535ed1a8a71795e50db8d87",
"sha256:70b39558712826e41f65e5f05a8d879361deaf84df8883e5dd0ec3d0da6ab66e"
"sha256:010f011c4e27d3d5eb01106fba6aac39d164842dfcd8709955c4638f5b11ccf8",
"sha256:f30a672a64d91cc2e3137765d088c5deec26416246f7a9e956eaf69a8d7ed49c"
],
"version": "==1.28.1"
"version": "==1.29.0"
},
"gunicorn": {
"hashes": [
@ -1374,59 +1374,59 @@
},
"zope.interface": {
"hashes": [
"sha256:02d3535aa18e34ce97c58d241120b7554f7d1cf4f8002fc9675cc7e7745d20e8",
"sha256:0378a42ec284b65706d9ef867600a4a31701a0d6773434e6537cfc744e3343f4",
"sha256:07d289358a8c565ea09e426590dd1179f93cf5ac3dd17d43fcc4fc63c1a9d275",
"sha256:0e6cdbdd94ae94d1433ab51f46a76df0f2cd041747c31baec1c1ffa4e76bd0c1",
"sha256:11354fb8b8bdc5cdd66358ed4f1f0ce739d78ff6d215d33b8f3ae282258c0f11",
"sha256:12588a46ae0a99f172c4524cbbc3bb870f32e0f8405e9fa11a5ef3fa3a808ad7",
"sha256:16caa44a06f6b0b2f7626ced4b193c1ae5d09c1b49c9b4962c93ae8aa2134f55",
"sha256:18c478b89b6505756f007dcf76a67224a23dcf0f365427742ed0c0473099caa4",
"sha256:221b41442cf4428fcda7fc958c9721c916709e2a3a9f584edd70f1493a09a762",
"sha256:26109c50ccbcc10f651f76277cfc05fba8418a907daccc300c9247f24b3158a2",
"sha256:28d8157f8c77662a1e0796a7d3cfa8910289131d4b4dd4e10b2686ab1309b67b",
"sha256:2c51689b7b40c7d9c7e8a678350e73dc647945a13b4e416e7a02bbf0c37bdb01",
"sha256:2ec58e1e1691dde4fbbd97f8610de0f8f1b1a38593653f7d3b8e931b9cd6d67f",
"sha256:416feb6500f7b6fc00d32271f6b8495e67188cb5eb51fc8e289b81fdf465a9cb",
"sha256:520352b18adea5478bbf387e9c77910a914985671fe36bc5ef19fdcb67a854bc",
"sha256:527415b5ca201b4add44026f70278fbc0b942cf0801a26ca5527cb0389b6151e",
"sha256:54243053316b5eec92affe43bbace7c8cd946bc0974a4aa39ff1371df0677b22",
"sha256:61b8454190b9cc87279232b6de28dee0bad040df879064bb2f0e505cda907918",
"sha256:672668729edcba0f2ee522ab177fcad91c81cfce991c24d8767765e2637d3515",
"sha256:67aa26097e194947d29f2b5a123830e03da1519bcce10cac034a51fcdb99c34f",
"sha256:6e7305e42b5f54e5ccf51820de46f0a7c951ba7cb9e3f519e908545b0f5628d0",
"sha256:7234ac6782ca43617de803735949f79b894f0c5d353fbc001d745503c69e6d1d",
"sha256:7426bea25bdf92f00fa52c7b30fcd2a2f71c21cf007178971b1f248b6c2d3145",
"sha256:74b331c5d5efdddf5bbd9e1f7d8cb91a0d6b9c4ba45ca3e9003047a84dca1a3b",
"sha256:79b6db1a18253db86e9bf1e99fa829d60fd3fc7ac04f4451c44e4bdcf6756a42",
"sha256:7d79cd354ae0a033ac7b86a2889c9e8bb0bb48243a6ed27fc5064ce49b842ada",
"sha256:823d1b4a6a028b8327e64865e2c81a8959ae9f4e7c9c8e0eec814f4f9b36b362",
"sha256:8715717a5861932b7fe7f3cbd498c82ff4132763e2fea182cc95e53850394ec1",
"sha256:89a6091f2d07936c8a96ce56f2000ecbef20fb420a94845e7d53913c558a6378",
"sha256:8af4b3116e4a37059bc8c7fe36d4a73d7c1d8802a1d8b6e549f1380d13a40160",
"sha256:8b4b0034e6c7f30133fa64a1cc276f8f1a155ef9529e7eb93a3c1728b40c0f5c",
"sha256:92195df3913c1de80062635bf64cd7bd0d0934a7fa1689b6d287d1cbbd16922c",
"sha256:96c2e68385f3848d58f19b2975a675532abdb65c8fa5f04d94b95b27b6b1ffa7",
"sha256:9c7044dbbf8c58420a9ef4ed6901f5a8b7698d90cd984d7f57a18c78474686f6",
"sha256:a1937efed7e3fe0ee74630e1960df887d8aa83c571e1cf4db9d15b9c181d457d",
"sha256:a38c10423a475a1658e2cb8f52cf84ec20a4c0adff724dd43a6b45183f499bc1",
"sha256:a413c424199bcbab71bf5fa7538246f27177fbd6dd74b2d9c5f34878658807f8",
"sha256:b18a855f8504743e0a2d8b75d008c7720d44e4c76687e13f959e35d9a13eb397",
"sha256:b4d59ab3608538e550a72cea13d3c209dd72b6e19e832688da7884081c01594e",
"sha256:b51d3f1cd87f488455f43046d72003689024b0fa9b2d53635db7523033b19996",
"sha256:c02105deda867d09cdd5088d08708f06d75759df6f83d8f7007b06f422908a30",
"sha256:c7b6032dc4490b0dcaf078f09f5b382dc35493cb7f473840368bf0de3196c2b6",
"sha256:c95b355dba2aaf5177dff943b25ded0529a7feb80021d5fdb114a99f0a1ef508",
"sha256:c980ae87863d76b1ea9a073d6d95554b4135032d34bc541be50c07d4a085821b",
"sha256:d12895cd083e35e9e032eb4b57645b91116f8979527381a8d864d1f6b8cb4a2e",
"sha256:d3cd9bad547a8e5fbe712a1dc1413aff1b917e8d39a2cd1389a6f933b7a21460",
"sha256:e8809b01f27f679e3023b9e2013051e0a3f17abff4228cb5197663afd8a0f2c7",
"sha256:f3c37b0dc1898e305aad4f7a1d75f6da83036588c28a9ce0afc681ff5245a601",
"sha256:f966765f54b536e791541458de84a737a6adba8467190f17a8fe7f85354ba908",
"sha256:fa939c2e2468142c9773443d4038e7c915b0cc1b670d3c9192bdc503f7ea73e9",
"sha256:fcc5c1f95102989d2e116ffc8467963554ce89f30a65a3ea86a4d06849c498d8"
"sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192",
"sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702",
"sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09",
"sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4",
"sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a",
"sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3",
"sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf",
"sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c",
"sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d",
"sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78",
"sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83",
"sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531",
"sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46",
"sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021",
"sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94",
"sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc",
"sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63",
"sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54",
"sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117",
"sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25",
"sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05",
"sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e",
"sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1",
"sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004",
"sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2",
"sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e",
"sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f",
"sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f",
"sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120",
"sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f",
"sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1",
"sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9",
"sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e",
"sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7",
"sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8",
"sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b",
"sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155",
"sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7",
"sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c",
"sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325",
"sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d",
"sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb",
"sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e",
"sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959",
"sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7",
"sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920",
"sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e",
"sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48",
"sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8",
"sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4",
"sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263"
],
"version": "==5.3.0"
"version": "==5.4.0"
}
},
"develop": {

View File

@ -4,7 +4,7 @@
---
[![](https://img.shields.io/discord/809154715984199690?label=Discord&style=flat-square)](https://discord.gg/KPnmtNWy)
[![](https://img.shields.io/discord/809154715984199690?label=Discord&style=flat-square)](https://discord.gg/jg33eMhnj6)
[![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/authentik/1?style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=1)
[![Tests](https://img.shields.io/azure-devops/tests/beryjuorg/authentik/1?compact_message&style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=1)
[![Code Coverage](https://img.shields.io/codecov/c/gh/beryju/authentik?style=flat-square)](https://codecov.io/gh/BeryJu/authentik)

View File

@ -1,3 +1,3 @@
"""authentik"""
__version__ = "2021.4.1"
__version__ = "2021.4.3"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -4,6 +4,7 @@ from binascii import Error
from typing import Any, Optional, Union
from rest_framework.authentication import BaseAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.request import Request
from structlog.stdlib import get_logger
@ -14,7 +15,7 @@ LOGGER = get_logger()
# pylint: disable=too-many-return-statements
def token_from_header(raw_header: bytes) -> Optional[Token]:
"""raw_header in the Format of `Basic dGVzdDp0ZXN0`"""
"""raw_header in the Format of `Bearer dGVzdDp0ZXN0`"""
auth_credentials = raw_header.decode()
if auth_credentials == "":
return None
@ -25,28 +26,27 @@ def token_from_header(raw_header: bytes) -> Optional[Token]:
auth_type, body = plain.split()
auth_credentials = f"{auth_type} {b64encode(body.encode()).decode()}"
except (UnicodeDecodeError, Error):
return None
raise AuthenticationFailed("Malformed header")
auth_type, auth_credentials = auth_credentials.split()
if auth_type.lower() not in ["basic", "bearer"]:
LOGGER.debug("Unsupported authentication type, denying", type=auth_type.lower())
return None
raise AuthenticationFailed("Unsupported authentication type")
password = auth_credentials
if auth_type.lower() == "basic":
try:
auth_credentials = b64decode(auth_credentials.encode()).decode()
except (UnicodeDecodeError, Error):
return None
raise AuthenticationFailed("Malformed header")
# Accept credentials with username and without
if ":" in auth_credentials:
_, password = auth_credentials.split(":")
else:
password = auth_credentials
if password == "": # nosec
return None
raise AuthenticationFailed("Malformed header")
tokens = Token.filter_not_expired(key=password, intent=TokenIntents.INTENT_API)
if not tokens.exists():
LOGGER.debug("Token not found")
return None
raise AuthenticationFailed("Token invalid/expired")
return tokens.first()
@ -58,10 +58,8 @@ class AuthentikTokenAuthentication(BaseAuthentication):
auth = get_authorization_header(request)
token = token_from_header(auth)
# None is only returned when the header isn't set.
if not token:
return None
return (token.user, None)
def authenticate_header(self, request: Request) -> str:
return "Bearer"

View File

@ -11,6 +11,29 @@ authentik API Browser
{% endblock %}
{% block body %}
<script>
function getCookie(name) {
let cookieValue = "";
if (document.cookie && document.cookie !== "") {
const cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
window.addEventListener('DOMContentLoaded', (event) => {
const rapidocEl = document.querySelector('rapi-doc');
rapidocEl.addEventListener('before-try', (e) => {
e.detail.request.headers.append('X-CSRFToken', getCookie("authentik_csrf"));
});
});
</script>
<rapi-doc
spec-url="{{ path }}"
heading-text="authentik"

View File

@ -3,6 +3,7 @@ from base64 import b64encode
from django.test import TestCase
from guardian.shortcuts import get_anonymous_user
from rest_framework.exceptions import AuthenticationFailed
from authentik.api.auth import token_from_header
from authentik.core.models import Token, TokenIntents
@ -28,17 +29,21 @@ class TestAPIAuth(TestCase):
def test_invalid_type(self):
"""Test invalid type"""
self.assertIsNone(token_from_header("foo bar".encode()))
with self.assertRaises(AuthenticationFailed):
token_from_header("foo bar".encode())
def test_invalid_decode(self):
"""Test invalid bas64"""
self.assertIsNone(token_from_header("Basic bar".encode()))
with self.assertRaises(AuthenticationFailed):
token_from_header("Basic bar".encode())
def test_invalid_empty_password(self):
"""Test invalid with empty password"""
self.assertIsNone(token_from_header("Basic :".encode()))
with self.assertRaises(AuthenticationFailed):
token_from_header("Basic :".encode())
def test_invalid_no_token(self):
"""Test invalid with no token"""
auth = b64encode(":abc".encode()).decode()
self.assertIsNone(token_from_header(f"Basic :{auth}".encode()))
with self.assertRaises(AuthenticationFailed):
auth = b64encode(":abc".encode()).decode()
self.assertIsNone(token_from_header(f"Basic :{auth}".encode()))

View File

@ -113,6 +113,7 @@ router.register("core/user_consent", UserConsentViewSet)
router.register("core/tokens", TokenViewSet)
router.register("outposts/outposts", OutpostViewSet)
router.register("outposts/instances", OutpostViewSet)
router.register("outposts/service_connections/all", ServiceConnectionViewSet)
router.register("outposts/service_connections/docker", DockerServiceConnectionViewSet)
router.register(

View File

@ -91,6 +91,15 @@ class ApplicationViewSet(ModelViewSet):
applications.append(application)
return applications
@swagger_auto_schema(
manual_parameters=[
openapi.Parameter(
name="superuser_full_list",
in_=openapi.IN_QUERY,
type=openapi.TYPE_BOOLEAN,
)
]
)
def list(self, request: Request) -> Response:
"""Custom list method that checks Policy based access instead of guardian"""
queryset = self._filter_queryset_for_list(self.get_queryset())
@ -98,6 +107,13 @@ class ApplicationViewSet(ModelViewSet):
should_cache = request.GET.get("search", "") == ""
superuser_full_list = (
str(request.GET.get("superuser_full_list", "false")).lower() == "true"
)
if superuser_full_list and request.user.is_superuser:
serializer = self.get_serializer(queryset, many=True)
return self.get_paginated_response(serializer.data)
allowed_applications = []
if not should_cache:
allowed_applications = self._get_allowed_applications(queryset)

View File

@ -1,6 +1,7 @@
"""PropertyMapping API Views"""
from json import dumps
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from guardian.shortcuts import get_objects_for_user
from rest_framework import mixins
@ -91,7 +92,9 @@ class PropertyMappingViewSet(
{
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": subclass.component,
# pyright: reportGeneralTypeIssues=false
"component": subclass().component,
"model_name": subclass._meta.model_name,
}
)
return Response(TypeCreateSerializer(data, many=True).data)
@ -100,6 +103,13 @@ class PropertyMappingViewSet(
@swagger_auto_schema(
request_body=PolicyTestSerializer(),
responses={200: PropertyMappingTestResultSerializer, 400: "Invalid parameters"},
manual_parameters=[
openapi.Parameter(
name="format_result",
in_=openapi.IN_QUERY,
type=openapi.TYPE_BOOLEAN,
)
],
)
@action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"])
# pylint: disable=unused-argument, invalid-name
@ -110,6 +120,8 @@ class PropertyMappingViewSet(
if not test_params.is_valid():
return Response(test_params.errors, status=400)
format_result = str(request.GET.get("format_result", "false")).lower() == "true"
# User permission check, only allow mapping testing for users that are readable
users = get_objects_for_user(request.user, "authentik_core.view_user").filter(
pk=test_params.validated_data["user"].pk
@ -124,7 +136,9 @@ class PropertyMappingViewSet(
self.request,
**test_params.validated_data.get("context", {}),
)
response_data["result"] = dumps(result)
response_data["result"] = dumps(
result, indent=(4 if format_result else None)
)
except Exception as exc: # pylint: disable=broad-except
response_data["result"] = str(exc)
response_data["successful"] = False

View File

@ -78,6 +78,7 @@ class ProviderViewSet(
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": subclass().component,
"model_name": subclass._meta.model_name,
}
)
data.append(
@ -85,6 +86,7 @@ class ProviderViewSet(
"name": _("SAML Provider from Metadata"),
"description": _("Create a SAML Provider by importing its Metadata."),
"component": "ak-provider-saml-import-form",
"model_name": "",
}
)
return Response(TypeCreateSerializer(data, many=True).data)

View File

@ -81,6 +81,7 @@ class SourceViewSet(
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": component,
"model_name": subclass._meta.model_name,
}
)
return Response(TypeCreateSerializer(data, many=True).data)

View File

@ -11,7 +11,7 @@ from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Token
from authentik.core.models import Token, TokenIntents
from authentik.events.models import Event, EventAction
from authentik.managed.api import ManagedSerializer
@ -64,7 +64,7 @@ class TokenViewSet(ModelViewSet):
ordering = ["expires"]
def perform_create(self, serializer: TokenSerializer):
serializer.save(user=self.request.user)
serializer.save(user=self.request.user, intent=TokenIntents.INTENT_API)
@permission_required("authentik_core.view_token_key")
@swagger_auto_schema(

View File

@ -1,4 +1,5 @@
"""User API Views"""
from django.http.response import Http404
from django.urls import reverse_lazy
from django.utils.http import urlencode
from drf_yasg.utils import swagger_auto_schema, swagger_serializer_method
@ -19,6 +20,7 @@ from authentik.core.middleware import (
)
from authentik.core.models import Token, TokenIntents, User
from authentik.events.models import EventAction
from authentik.flows.models import Flow, FlowDesignation
class UserSerializer(ModelSerializer):
@ -121,12 +123,16 @@ class UserViewSet(ModelViewSet):
@permission_required("authentik_core.reset_user_password")
@swagger_auto_schema(
responses={"200": LinkSerializer(many=False)},
responses={"200": LinkSerializer(many=False), "404": "No recovery flow found."},
)
@action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=invalid-name, unused-argument
def recovery(self, request: Request, pk: int) -> Response:
"""Create a temporary link that a user can use to recover their accounts"""
# Check that there is a recovery flow, if not return an error
flow = Flow.with_policy(request, designation=FlowDesignation.RECOVERY)
if not flow:
raise Http404
user: User = self.get_object()
token, __ = Token.objects.get_or_create(
identifier=f"{user.uid}-password-reset",

View File

@ -48,6 +48,7 @@ class TypeCreateSerializer(PassiveSerializer):
name = CharField(required=True)
description = CharField(required=True)
component = CharField(required=True)
model_name = CharField(required=True)
class CacheSerializer(PassiveSerializer):

View File

@ -1,6 +1,7 @@
"""Channels base classes"""
from channels.exceptions import DenyConnection
from channels.generic.websocket import JsonWebsocketConsumer
from rest_framework.exceptions import AuthenticationFailed
from structlog.stdlib import get_logger
from authentik.api.auth import token_from_header
@ -22,9 +23,13 @@ class AuthJsonConsumer(JsonWebsocketConsumer):
raw_header = headers[b"authorization"]
token = token_from_header(raw_header)
if not token:
LOGGER.warning("Failed to authenticate")
try:
token = token_from_header(raw_header)
# token is only None when no header was given, in which case we deny too
if not token:
raise DenyConnection()
except AuthenticationFailed as exc:
LOGGER.warning("Failed to authenticate", exc=exc)
raise DenyConnection()
self.user = token.user

View File

@ -2,7 +2,7 @@
from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Token, User
from authentik.core.models import Token, TokenIntents, User
class TestTokenAPI(APITestCase):
@ -19,4 +19,6 @@ class TestTokenAPI(APITestCase):
reverse("authentik_api:token-list"), {"identifier": "test-token"}
)
self.assertEqual(response.status_code, 201)
self.assertEqual(Token.objects.get(identifier="test-token").user, self.user)
token = Token.objects.get(identifier="test-token")
self.assertEqual(token.user, self.user)
self.assertEqual(token.intent, TokenIntents.INTENT_API)

View File

@ -153,10 +153,6 @@ class EventViewSet(ReadOnlyModelViewSet):
data = []
for value, name in EventAction.choices:
data.append(
{
"name": name,
"description": "",
"component": value,
}
{"name": name, "description": "", "component": value, "model_name": ""}
)
return Response(TypeCreateSerializer(data, many=True).data)

View File

@ -4,6 +4,7 @@ from typing import Iterable
from drf_yasg.utils import swagger_auto_schema
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.fields import BooleanField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, SerializerMethodField
@ -19,6 +20,12 @@ from authentik.lib.utils.reflection import all_subclasses
LOGGER = get_logger()
class StageUserSettingSerializer(UserSettingSerializer):
"""User settings but can include a configure flow"""
configure_flow = BooleanField(required=False)
class StageSerializer(ModelSerializer, MetaNameSerializer):
"""Stage Serializer"""
@ -73,12 +80,13 @@ class StageViewSet(
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": subclass().component,
"model_name": subclass._meta.model_name,
}
)
data = sorted(data, key=lambda x: x["name"])
return Response(TypeCreateSerializer(data, many=True).data)
@swagger_auto_schema(responses={200: UserSettingSerializer(many=True)})
@swagger_auto_schema(responses={200: StageUserSettingSerializer(many=True)})
@action(detail=False, pagination_class=None, filter_backends=[])
def user_settings(self, request: Request) -> Response:
"""Get all stages the user can configure"""
@ -89,6 +97,10 @@ class StageViewSet(
if not user_settings:
continue
user_settings.initial_data["object_uid"] = str(stage.pk)
if hasattr(stage, "configure_flow"):
user_settings.initial_data["configure_flow"] = bool(
stage.configure_flow
)
if not user_settings.is_valid():
LOGGER.warning(user_settings.errors)
matching_stages.append(user_settings.initial_data)

View File

@ -127,6 +127,7 @@ class FlowExecutorView(APIView):
@swagger_auto_schema(
responses={
200: Challenge(),
404: "No Token found", # This error can be raised by the email stage
},
request_body=no_body,
manual_parameters=[

View File

@ -82,6 +82,7 @@ class ServiceConnectionViewSet(
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": subclass().component,
"model_name": subclass._meta.model_name,
}
)
return Response(TypeCreateSerializer(data, many=True).data)

View File

@ -356,7 +356,7 @@ class Outpost(models.Model):
intent=TokenIntents.INTENT_API,
description=f"Autogenerated by authentik for Outpost {self.name}",
expiring=False,
managed="goauthentik.io/outpost",
managed=f"goauthentik.io/outpost/{self.token_identifier}",
)
def get_required_objects(self) -> Iterable[models.Model]:

View File

@ -67,6 +67,8 @@ def outpost_controller(self: MonitoredTask, outpost_pk: str):
outpost: Outpost = Outpost.objects.get(pk=outpost_pk)
self.set_uid(slugify(outpost.name))
try:
if not outpost.service_connection:
return
if outpost.type == OutpostType.PROXY:
service_connection = outpost.service_connection
if isinstance(service_connection, DockerServiceConnection):

View File

@ -108,6 +108,7 @@ class PolicyViewSet(
"name": subclass._meta.verbose_name,
"description": subclass.__doc__,
"component": subclass().component,
"model_name": subclass._meta.model_name,
}
)
return Response(TypeCreateSerializer(data, many=True).data)

View File

@ -1,13 +1,23 @@
"""Test authorize view"""
from django.test import RequestFactory, TestCase
from django.urls import reverse
from django.utils.encoding import force_str
from authentik.core.models import Application, User
from authentik.flows.challenge import ChallengeTypes
from authentik.flows.models import Flow
from authentik.providers.oauth2.errors import (
AuthorizeError,
ClientIdError,
RedirectUriError,
)
from authentik.providers.oauth2.models import OAuth2Provider
from authentik.providers.oauth2.generators import generate_client_id
from authentik.providers.oauth2.models import (
AuthorizationCode,
GrantTypes,
OAuth2Provider,
RefreshToken,
)
from authentik.providers.oauth2.views.authorize import OAuthAuthorizationParams
@ -32,15 +42,194 @@ class TestViewsAuthorize(TestCase):
)
OAuthAuthorizationParams.from_request(request)
def test_missing_redirect_uri(self):
"""test missing redirect URI"""
def test_request(self):
"""test request param"""
OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
with self.assertRaises(AuthorizeError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "http://local.invalid",
"request": "foo",
},
)
OAuthAuthorizationParams.from_request(request)
def test_redirect_uri(self):
"""test missing/invalid redirect URI"""
OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/", data={"response_type": "code", "client_id": "test"}
)
OAuthAuthorizationParams.from_request(request)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "http://localhost",
},
)
OAuthAuthorizationParams.from_request(request)
def test_response_type(self):
"""test response_type"""
OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "http://local.invalid",
},
)
self.assertEqual(
OAuthAuthorizationParams.from_request(request).grant_type,
GrantTypes.AUTHORIZATION_CODE,
)
request = self.factory.get(
"/",
data={
"response_type": "id_token",
"client_id": "test",
"redirect_uri": "http://local.invalid",
"scope": "openid",
"state": "foo",
},
)
self.assertEqual(
OAuthAuthorizationParams.from_request(request).grant_type,
GrantTypes.IMPLICIT,
)
# Implicit without openid scope
with self.assertRaises(AuthorizeError):
request = self.factory.get(
"/",
data={
"response_type": "id_token",
"client_id": "test",
"redirect_uri": "http://local.invalid",
"state": "foo",
},
)
self.assertEqual(
OAuthAuthorizationParams.from_request(request).grant_type,
GrantTypes.IMPLICIT,
)
request = self.factory.get(
"/",
data={
"response_type": "code token",
"client_id": "test",
"redirect_uri": "http://local.invalid",
"scope": "openid",
"state": "foo",
},
)
self.assertEqual(
OAuthAuthorizationParams.from_request(request).grant_type, GrantTypes.HYBRID
)
with self.assertRaises(AuthorizeError):
request = self.factory.get(
"/",
data={
"response_type": "invalid",
"client_id": "test",
"redirect_uri": "http://local.invalid",
},
)
OAuthAuthorizationParams.from_request(request)
def test_full_code(self):
"""Test full authorization"""
flow = Flow.objects.create(slug="empty")
provider = OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=flow,
redirect_uris="http://localhost",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_client_id()
user = User.objects.get(username="akadmin")
self.client.force_login(user)
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "code",
"client_id": "test",
"state": state,
"redirect_uri": "http://localhost",
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
self.assertJSONEqual(
force_str(response.content),
{
"type": ChallengeTypes.REDIRECT.value,
"to": f"http://localhost?code={code.code}&state={state}",
},
)
def test_full_implicit(self):
"""Test full authorization"""
flow = Flow.objects.create(slug="empty")
provider = OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=flow,
redirect_uris="http://localhost",
)
Application.objects.create(name="app", slug="app", provider=provider)
state = generate_client_id()
user = User.objects.get(username="akadmin")
self.client.force_login(user)
# Step 1, initiate params and get redirect to flow
self.client.get(
reverse("authentik_providers_oauth2:authorize"),
data={
"response_type": "id_token",
"client_id": "test",
"state": state,
"scope": "openid",
"redirect_uri": "http://localhost",
},
)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
token: RefreshToken = RefreshToken.objects.filter(user=user).first()
self.assertJSONEqual(
force_str(response.content),
{
"type": ChallengeTypes.REDIRECT.value,
"to": (
f"http://localhost#access_token={token.access_token}"
f"&id_token={provider.encode(token.id_token.to_dict())}&token_type=bearer"
f"&expires_in=600&state={state}"
),
},
)

View File

@ -0,0 +1,171 @@
"""Test token view"""
from base64 import b64encode
from django.test import RequestFactory, TestCase
from django.urls import reverse
from django.utils.encoding import force_str
from authentik.core.models import User
from authentik.flows.models import Flow
from authentik.providers.oauth2.constants import (
GRANT_TYPE_AUTHORIZATION_CODE,
GRANT_TYPE_REFRESH_TOKEN,
)
from authentik.providers.oauth2.generators import (
generate_client_id,
generate_client_secret,
)
from authentik.providers.oauth2.models import (
AuthorizationCode,
OAuth2Provider,
RefreshToken,
)
from authentik.providers.oauth2.views.token import TokenParams
class TestViewsToken(TestCase):
"""Test token view"""
def setUp(self) -> None:
super().setUp()
self.factory = RequestFactory()
def test_request_auth_code(self):
"""test request param"""
provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_client_id(),
client_secret=generate_client_secret(),
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
header = b64encode(
f"{provider.client_id}:{provider.client_secret}".encode()
).decode()
user = User.objects.get(username="akadmin")
code = AuthorizationCode.objects.create(
code="foobar", provider=provider, user=user
)
request = self.factory.post(
"/",
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
"redirect_uri": "http://local.invalid",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
params = TokenParams.from_request(request)
self.assertEqual(params.provider, provider)
def test_request_refresh_token(self):
"""test request param"""
provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_client_id(),
client_secret=generate_client_secret(),
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
header = b64encode(
f"{provider.client_id}:{provider.client_secret}".encode()
).decode()
user = User.objects.get(username="akadmin")
token: RefreshToken = RefreshToken.objects.create(
provider=provider,
user=user,
refresh_token=generate_client_id(),
)
request = self.factory.post(
"/",
data={
"grant_type": GRANT_TYPE_REFRESH_TOKEN,
"refresh_token": token.refresh_token,
"redirect_uri": "http://local.invalid",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
params = TokenParams.from_request(request)
self.assertEqual(params.provider, provider)
def test_auth_code_view(self):
"""test request param"""
provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_client_id(),
client_secret=generate_client_secret(),
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
header = b64encode(
f"{provider.client_id}:{provider.client_secret}".encode()
).decode()
user = User.objects.get(username="akadmin")
code = AuthorizationCode.objects.create(
code="foobar", provider=provider, user=user
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_AUTHORIZATION_CODE,
"code": code.code,
"redirect_uri": "http://local.invalid",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
new_token: RefreshToken = RefreshToken.objects.filter(user=user).first()
self.assertJSONEqual(
force_str(response.content),
{
"access_token": new_token.access_token,
"refresh_token": new_token.refresh_token,
"token_type": "bearer",
"expires_in": 600,
"id_token": provider.encode(
new_token.id_token.to_dict(),
),
},
)
def test_refresh_token_view(self):
"""test request param"""
provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_client_id(),
client_secret=generate_client_secret(),
authorization_flow=Flow.objects.first(),
redirect_uris="http://local.invalid",
)
header = b64encode(
f"{provider.client_id}:{provider.client_secret}".encode()
).decode()
user = User.objects.get(username="akadmin")
token: RefreshToken = RefreshToken.objects.create(
provider=provider,
user=user,
refresh_token=generate_client_id(),
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"grant_type": GRANT_TYPE_REFRESH_TOKEN,
"refresh_token": token.refresh_token,
"redirect_uri": "http://local.invalid",
},
HTTP_AUTHORIZATION=f"Basic {header}",
)
new_token: RefreshToken = (
RefreshToken.objects.filter(user=user).exclude(pk=token.pk).first()
)
self.assertJSONEqual(
force_str(response.content),
{
"access_token": new_token.access_token,
"refresh_token": new_token.refresh_token,
"token_type": "bearer",
"expires_in": 600,
"id_token": provider.encode(
new_token.id_token.to_dict(),
),
},
)

View File

@ -3,6 +3,7 @@ import re
from base64 import b64decode
from binascii import Error
from typing import Optional
from urllib.parse import urlparse
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.utils.cache import patch_vary_headers
@ -25,15 +26,34 @@ class TokenResponse(JsonResponse):
self["Pragma"] = "no-cache"
def cors_allow_any(request, response):
"""
Add headers to permit CORS requests from any origin, with or without credentials,
with any headers.
"""
def cors_allow_any(request: HttpRequest, response: HttpResponse, *allowed_origins: str):
"""Add headers to permit CORS requests from any origin, with or without credentials,
with any headers."""
origin = request.META.get("HTTP_ORIGIN")
if not origin:
return response
# OPTIONS requests don't have an authorization header -> hence
# we can't extract the provider this request is for
# so for options requests we allow the calling origin without checking
allowed = request.method == "OPTIONS"
received_origin = urlparse(origin)
for allowed_origin in allowed_origins:
url = urlparse(allowed_origin)
if (
received_origin.scheme == url.scheme
and received_origin.hostname == url.hostname
and received_origin.port == url.port
):
allowed = True
if not allowed:
LOGGER.warning(
"CORS: Origin is not an allowed origin",
requested=origin,
allowed=allowed_origins,
)
return response
# From the CORS spec: The string "*" cannot be used for a resource that supports credentials.
response["Access-Control-Allow-Origin"] = origin
patch_vary_headers(response, ["Origin"])

View File

@ -6,7 +6,7 @@ from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
from uuid import uuid4
from django.http import HttpRequest, HttpResponse
from django.http.response import Http404, HttpResponseRedirect
from django.http.response import Http404, HttpResponseBadRequest, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect
from django.utils import timezone
from django.utils.translation import gettext as _
@ -236,6 +236,9 @@ class OAuthFulfillmentStage(StageView):
# pylint: disable=unused-argument
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
"""final Stage of an OAuth2 Flow"""
if PLAN_CONTEXT_PARAMS not in self.executor.plan.context:
LOGGER.warning("Got to fulfillment stage with no pending context")
return HttpResponseBadRequest()
self.params: OAuthAuthorizationParams = self.executor.plan.context.pop(
PLAN_CONTEXT_PARAMS
)

View File

@ -30,6 +30,8 @@ PLAN_CONTEXT_SCOPES = "scopes"
class ProviderInfoView(View):
"""OpenID-compliant Provider Info"""
provider: OAuth2Provider
def get_info(self, provider: OAuth2Provider) -> dict[str, Any]:
"""Get dictionary for OpenID Connect information"""
scopes = list(
@ -95,19 +97,20 @@ class ProviderInfoView(View):
}
# pylint: disable=unused-argument
def get(
self, request: HttpRequest, application_slug: str, *args, **kwargs
) -> HttpResponse:
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
"""OpenID-compliant Provider Info"""
return JsonResponse(
self.get_info(self.provider), json_dumps_params={"indent": 2}
)
def dispatch(
self, request: HttpRequest, application_slug: str, *args: Any, **kwargs: Any
) -> HttpResponse:
# Since this view only supports get, we can statically set the CORS headers
application = get_object_or_404(Application, slug=application_slug)
provider: OAuth2Provider = get_object_or_404(
self.provider: OAuth2Provider = get_object_or_404(
OAuth2Provider, pk=application.provider_id
)
return JsonResponse(self.get_info(provider), json_dumps_params={"indent": 2})
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
# Since this view only supports get, we can statically set the CORS headers
response = super().dispatch(request, *args, **kwargs)
cors_allow_any(request, response)
cors_allow_any(request, response, *self.provider.redirect_uris.split("\n"))
return response

View File

@ -198,7 +198,7 @@ class TokenView(View):
response_dict = {
"access_token": refresh_token.access_token,
"refresh_token": refresh_token.refresh_token,
"token_type": "Bearer",
"token_type": "bearer",
"expires_in": timedelta_from_string(
self.params.provider.token_validity
).seconds,

View File

@ -1,7 +1,8 @@
"""authentik OAuth2 OpenID Userinfo views"""
from typing import Any
from typing import Any, Optional
from django.http import HttpRequest, HttpResponse
from django.http.response import HttpResponseBadRequest
from django.utils.translation import gettext_lazy as _
from django.views import View
from structlog.stdlib import get_logger
@ -22,6 +23,8 @@ class UserInfoView(View):
"""Create a dictionary with all the requested claims about the End-User.
See: http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse"""
token: Optional[RefreshToken]
def get_scope_descriptions(self, scopes: list[str]) -> list[dict[str, str]]:
"""Get a list of all Scopes's descriptions"""
scope_descriptions = []
@ -79,16 +82,25 @@ class UserInfoView(View):
final_claims.update(value)
return final_claims
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
self.token = kwargs.get("token", None)
response = super().dispatch(request, *args, **kwargs)
allowed_origins = []
if self.token:
allowed_origins = self.token.provider.redirect_uris.split("\n")
cors_allow_any(self.request, response, *allowed_origins)
return response
def options(self, request: HttpRequest) -> HttpResponse:
return cors_allow_any(self.request, TokenResponse({}))
return TokenResponse({})
def get(self, request: HttpRequest, **kwargs) -> HttpResponse:
"""Handle GET Requests for UserInfo"""
token: RefreshToken = kwargs["token"]
claims = self.get_claims(token)
claims["sub"] = token.id_token.sub
if not self.token:
return HttpResponseBadRequest()
claims = self.get_claims(self.token)
claims["sub"] = self.token.id_token.sub
response = TokenResponse(claims)
cors_allow_any(self.request, response)
return response
def post(self, request: HttpRequest, **kwargs) -> HttpResponse:

View File

@ -21,7 +21,7 @@ class ProxyScopeMappingManager(ObjectManager):
EnsureExists(
ScopeMapping,
"goauthentik.io/providers/proxy/scope-proxy",
name="authentik default OAuth Mapping: proxy outpost",
name="authentik default OAuth Mapping: Proxy outpost",
scope_name=SCOPE_AK_PROXY,
expression=SCOPE_AK_PROXY_EXPRESSION,
),

View File

@ -1,13 +1,12 @@
"""Channels Messages storage"""
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.contrib.messages.storage.base import Message
from django.contrib.messages.storage.fallback import FallbackStorage
from django.contrib.messages.storage.base import BaseStorage, Message
from django.core.cache import cache
from django.http.request import HttpRequest
class ChannelsStorage(FallbackStorage):
class ChannelsStorage(BaseStorage):
"""Send contrib.messages over websocket"""
def __init__(self, request: HttpRequest) -> None:
@ -15,6 +14,9 @@ class ChannelsStorage(FallbackStorage):
super().__init__(request)
self.channel = get_channel_layer()
def _get(self):
return [], True
def _store(self, messages: list[Message], response, *args, **kwargs):
prefix = f"user_{self.request.session.session_key}_messages_"
keys = cache.keys(f"{prefix}*")

View File

@ -254,8 +254,8 @@ EMAIL_HOST = CONFIG.y("email.host")
EMAIL_PORT = int(CONFIG.y("email.port"))
EMAIL_HOST_USER = CONFIG.y("email.username")
EMAIL_HOST_PASSWORD = CONFIG.y("email.password")
EMAIL_USE_TLS = CONFIG.y("email.use_tls")
EMAIL_USE_SSL = CONFIG.y("email.use_ssl")
EMAIL_USE_TLS = CONFIG.y_bool("email.use_tls", True)
EMAIL_USE_SSL = CONFIG.y_bool("email.use_ssl", False)
EMAIL_TIMEOUT = int(CONFIG.y("email.timeout"))
DEFAULT_FROM_EMAIL = CONFIG.y("email.from")
SERVER_EMAIL = DEFAULT_FROM_EMAIL

View File

@ -1,9 +1,11 @@
"""Sync LDAP Users and groups into authentik"""
import ldap3
import ldap3.core.exceptions
from django.core.exceptions import FieldError
from django.db.utils import IntegrityError
from authentik.core.models import Group
from authentik.events.models import Event, EventAction
from authentik.sources.ldap.sync.base import LDAP_UNIQUENESS, BaseLDAPSynchronizer
@ -47,14 +49,17 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
"defaults": defaults,
}
)
except IntegrityError as exc:
self._logger.warning("Failed to create group", exc=exc)
self._logger.warning(
(
"To merge new group with existing group, set the group's "
except (IntegrityError, FieldError) as exc:
Event.new(
EventAction.CONFIGURATION_ERROR,
message=(
f"Failed to create group: {str(exc)} "
"To merge new group with existing group, set the groups's "
f"Attribute '{LDAP_UNIQUENESS}' to '{uniq}'"
)
)
),
source=self._source,
dn=group_dn,
).save()
else:
self._logger.debug("Synced group", group=ak_group.name, created=created)
group_count += 1

View File

@ -3,6 +3,7 @@ from datetime import datetime
import ldap3
import ldap3.core.exceptions
from django.core.exceptions import FieldError
from django.db.utils import IntegrityError
from pytz import UTC
@ -48,7 +49,7 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer):
"defaults": defaults,
}
)
except IntegrityError as exc:
except (IntegrityError, FieldError) as exc:
Event.new(
EventAction.CONFIGURATION_ERROR,
message=(

View File

@ -5,6 +5,7 @@ from rest_framework.decorators import action
from rest_framework.fields import BooleanField, CharField, SerializerMethodField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import SourceSerializer
@ -47,6 +48,20 @@ class OAuthSourceSerializer(SourceSerializer):
"""Get source's type configuration"""
return SourceTypeSerializer(instace.type).data
def validate(self, attrs: dict) -> dict:
provider_type = MANAGER.find_type(attrs.get("provider_type", ""))
for url in [
"authorization_url",
"access_token_url",
"profile_url",
]:
if getattr(provider_type, url, None) is None:
if url not in attrs:
raise ValidationError(
f"{url} is required for provider {provider_type.name}"
)
return attrs
class Meta:
model = OAuthSource
fields = SourceSerializer.Meta.fields + [

View File

@ -9,6 +9,7 @@ from requests.models import Response
from structlog.stdlib import get_logger
from authentik import __version__
from authentik.events.models import Event, EventAction
from authentik.sources.oauth.models import OAuthSource
LOGGER = get_logger()
@ -59,7 +60,16 @@ class BaseOAuthClient:
args.update(additional)
params = urlencode(args)
LOGGER.info("redirect args", **args)
return f"{self.source.authorization_url}?{params}"
base_url = self.source.type.authorization_url
if self.source.authorization_url:
base_url = self.source.authorization_url
if base_url == "":
Event.new(
EventAction.CONFIGURATION_ERROR,
source=self.source,
message="Source has an empty authorization URL.",
).save()
return f"{base_url}?{params}"
def parse_raw_token(self, raw_token: str) -> dict[str, Any]:
"Parse token and secret from raw token response."

View File

@ -28,9 +28,12 @@ class OAuthClient(BaseOAuthClient):
if raw_token is not None and verifier is not None:
token = self.parse_raw_token(raw_token)
try:
access_token_url: str = self.source.type.access_token_url or ""
if self.source.access_token_url:
access_token_url = self.source.access_token_url
response = self.do_request(
"post",
self.source.access_token_url,
access_token_url,
token=token,
headers=self._default_headers,
oauth_verifier=verifier,
@ -48,9 +51,12 @@ class OAuthClient(BaseOAuthClient):
"Fetch the OAuth request token. Only required for OAuth 1.0."
callback = self.request.build_absolute_uri(self.callback)
try:
request_token_url: str = self.source.type.request_token_url or ""
if self.source.request_token_url:
request_token_url = self.source.request_token_url
response = self.do_request(
"post",
self.source.request_token_url,
request_token_url,
headers=self._default_headers,
oauth_callback=callback,
)

View File

@ -56,9 +56,12 @@ class OAuth2Client(BaseOAuthClient):
LOGGER.warning("No code returned by the source")
return None
try:
access_token_url = self.source.type.access_token_url or ""
if self.source.access_token_url:
access_token_url = self.source.access_token_url
response = self.session.request(
"post",
self.source.access_token_url,
access_token_url,
data=args,
headers=self._default_headers,
)

View File

@ -0,0 +1,43 @@
# Generated by Django 3.2 on 2021-04-16 07:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_oauth", "0002_auto_20200520_1108"),
]
operations = [
migrations.AlterField(
model_name="oauthsource",
name="access_token_url",
field=models.CharField(
blank=True,
help_text="URL used by authentik to retrive tokens.",
max_length=255,
verbose_name="Access Token URL",
),
),
migrations.AlterField(
model_name="oauthsource",
name="authorization_url",
field=models.CharField(
blank=True,
help_text="URL the user is redirect to to conest the flow.",
max_length=255,
verbose_name="Authorization URL",
),
),
migrations.AlterField(
model_name="oauthsource",
name="profile_url",
field=models.CharField(
blank=True,
help_text="URL used by authentik to get user information.",
max_length=255,
verbose_name="Profile URL",
),
),
]

View File

@ -0,0 +1,79 @@
# Generated by Django 3.2 on 2021-04-17 19:00
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def update_empty_urls(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
OAuthSource = apps.get_model("authentik_sources_oauth", "oauthsource")
db_alias = schema_editor.connection.alias
for source in OAuthSource.objects.using(db_alias).all():
changed = False
if source.access_token_url == "":
source.access_token_url = None
changed = True
if source.authorization_url == "":
source.authorization_url = None
changed = True
if source.profile_url == "":
source.profile_url = None
changed = True
if source.request_token_url == "":
source.request_token_url = None
changed = True
if changed:
source.save()
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_oauth", "0003_auto_20210416_0726"),
]
operations = [
migrations.AlterField(
model_name="oauthsource",
name="access_token_url",
field=models.CharField(
help_text="URL used by authentik to retrive tokens.",
max_length=255,
null=True,
verbose_name="Access Token URL",
),
),
migrations.AlterField(
model_name="oauthsource",
name="authorization_url",
field=models.CharField(
help_text="URL the user is redirect to to conest the flow.",
max_length=255,
null=True,
verbose_name="Authorization URL",
),
),
migrations.AlterField(
model_name="oauthsource",
name="profile_url",
field=models.CharField(
help_text="URL used by authentik to get user information.",
max_length=255,
null=True,
verbose_name="Profile URL",
),
),
migrations.AlterField(
model_name="oauthsource",
name="request_token_url",
field=models.CharField(
help_text="URL used to request the initial token. This URL is only required for OAuth 1.",
max_length=255,
null=True,
verbose_name="Request Token URL",
),
),
migrations.RunPython(update_empty_urls),
]

View File

@ -19,7 +19,7 @@ class OAuthSource(Source):
provider_type = models.CharField(max_length=255)
request_token_url = models.CharField(
blank=True,
null=True,
max_length=255,
verbose_name=_("Request Token URL"),
help_text=_(
@ -28,16 +28,19 @@ class OAuthSource(Source):
)
authorization_url = models.CharField(
max_length=255,
null=True,
verbose_name=_("Authorization URL"),
help_text=_("URL the user is redirect to to conest the flow."),
)
access_token_url = models.CharField(
max_length=255,
null=True,
verbose_name=_("Access Token URL"),
help_text=_("URL used by authentik to retrive tokens."),
)
profile_url = models.CharField(
max_length=255,
null=True,
verbose_name=_("Profile URL"),
help_text=_("URL used by authentik to get user information."),
)
@ -49,7 +52,7 @@ class OAuthSource(Source):
"""Return the provider instance for this source"""
from authentik.sources.oauth.types.manager import MANAGER
return MANAGER.find_type(self)
return MANAGER.find_type(self.provider_type)
@property
def component(self) -> str:
@ -160,6 +163,16 @@ class OpenIDOAuthSource(OAuthSource):
verbose_name_plural = _("OpenID OAuth Sources")
class PlexOAuthSource(OAuthSource):
"""Login using plex.tv."""
class Meta:
abstract = True
verbose_name = _("Plex OAuth Source")
verbose_name_plural = _("Plex OAuth Sources")
class UserOAuthSourceConnection(UserSourceConnection):
"""Authorized remote OAuth provider."""

View File

@ -9,4 +9,5 @@ AUTHENTIK_SOURCES_OAUTH_TYPES = [
"authentik.sources.oauth.types.twitter",
"authentik.sources.oauth.types.azure_ad",
"authentik.sources.oauth.types.oidc",
"authentik.sources.oauth.types.plex",
]

View File

@ -2,6 +2,7 @@
from django.test import TestCase
from django.urls import reverse
from authentik.sources.oauth.api.source import OAuthSourceSerializer
from authentik.sources.oauth.models import OAuthSource
@ -18,6 +19,31 @@ class TestOAuthSource(TestCase):
consumer_key="",
)
def test_api_validate(self):
"""Test API validation"""
self.assertTrue(
OAuthSourceSerializer(
data={
"name": "foo",
"slug": "bar",
"provider_type": "google",
"consumer_key": "foo",
"consumer_secret": "foo",
}
).is_valid()
)
self.assertFalse(
OAuthSourceSerializer(
data={
"name": "foo",
"slug": "bar",
"provider_type": "openid-connect",
"consumer_key": "foo",
"consumer_secret": "foo",
}
).is_valid()
)
def test_source_redirect(self):
"""test redirect view"""
self.client.get(

View File

@ -1,6 +1,6 @@
"""Source type manager"""
from enum import Enum
from typing import TYPE_CHECKING, Callable, Optional
from typing import Callable, Optional
from structlog.stdlib import get_logger
@ -9,9 +9,6 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect
LOGGER = get_logger()
if TYPE_CHECKING:
from authentik.sources.oauth.models import OAuthSource
class RequestKind(Enum):
"""Enum of OAuth Request types"""
@ -58,24 +55,24 @@ class SourceTypeManager:
"""Get list of tuples of all registered names"""
return [(x.slug, x.name) for x in self.__sources]
def find_type(self, source: "OAuthSource") -> SourceType:
def find_type(self, type_name: str) -> SourceType:
"""Find type based on source"""
found_type = None
for src_type in self.__sources:
if src_type.slug == source.provider_type:
if src_type.slug == type_name:
return src_type
if not found_type:
found_type = SourceType()
LOGGER.warning(
"no matching type found, using default",
wanted=source.provider_type,
have=[x.name for x in self.__sources],
wanted=type_name,
have=[x.slug for x in self.__sources],
)
return found_type
def find(self, source: "OAuthSource", kind: RequestKind) -> Callable:
def find(self, type_name: str, kind: RequestKind) -> Callable:
"""Find fitting Source Type"""
found_type = self.find_type(source)
found_type = self.find_type(type_name)
if kind == RequestKind.CALLBACK:
return found_type.callback_view
if kind == RequestKind.REDIRECT:

View File

@ -0,0 +1,134 @@
"""Plex OAuth Views"""
from typing import Any, Optional
from urllib.parse import urlencode
from django.http.response import Http404
from requests import post
from requests.api import get
from requests.exceptions import RequestException
from structlog.stdlib import get_logger
from authentik import __version__
from authentik.sources.oauth.clients.oauth2 import OAuth2Client
from authentik.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
from authentik.sources.oauth.types.manager import MANAGER, SourceType
from authentik.sources.oauth.views.callback import OAuthCallback
from authentik.sources.oauth.views.redirect import OAuthRedirect
LOGGER = get_logger()
SESSION_ID_KEY = "PLEX_ID"
SESSION_CODE_KEY = "PLEX_CODE"
DEFAULT_PAYLOAD = {
"X-Plex-Product": "authentik",
"X-Plex-Version": __version__,
"X-Plex-Device-Vendor": "BeryJu.org",
}
class PlexRedirect(OAuthRedirect):
"""Plex Auth redirect, get a pin then redirect to a URL to claim it"""
headers = {}
def get_pin(self, **data) -> dict:
"""Get plex pin that the user will claim
https://forums.plex.tv/t/authenticating-with-plex/609370"""
return post(
"https://plex.tv/api/v2/pins.json?strong=true",
data=data,
headers=self.headers,
).json()
def get_redirect_url(self, **kwargs) -> str:
slug = kwargs.get("source_slug", "")
self.headers = {"Origin": self.request.build_absolute_uri("/")}
try:
source: OAuthSource = OAuthSource.objects.get(slug=slug)
except OAuthSource.DoesNotExist:
raise Http404(f"Unknown OAuth source '{slug}'.")
else:
payload = DEFAULT_PAYLOAD.copy()
payload["X-Plex-Client-Identifier"] = source.consumer_key
# Get a pin first
pin = self.get_pin(**payload)
LOGGER.debug("Got pin", **pin)
self.request.session[SESSION_ID_KEY] = pin["id"]
self.request.session[SESSION_CODE_KEY] = pin["code"]
qs = {
"clientID": source.consumer_key,
"code": pin["code"],
"forwardUrl": self.request.build_absolute_uri(
self.get_callback_url(source)
),
}
return f"https://app.plex.tv/auth#!?{urlencode(qs)}"
class PlexOAuthClient(OAuth2Client):
"""Retrive the plex token after authentication, then ask the plex API about user info"""
def check_application_state(self) -> bool:
return SESSION_ID_KEY in self.request.session
def get_access_token(self, **request_kwargs) -> Optional[dict[str, Any]]:
payload = dict(DEFAULT_PAYLOAD)
payload["X-Plex-Client-Identifier"] = self.source.consumer_key
payload["Accept"] = "application/json"
response = get(
f"https://plex.tv/api/v2/pins/{self.request.session[SESSION_ID_KEY]}",
headers=payload,
)
response.raise_for_status()
token = response.json()["authToken"]
return {"plex_token": token}
def get_profile_info(self, token: dict[str, str]) -> Optional[dict[str, Any]]:
"Fetch user profile information."
qs = {"X-Plex-Token": token["plex_token"]}
try:
response = self.do_request(
"get", f"https://plex.tv/users/account.json?{urlencode(qs)}"
)
response.raise_for_status()
except RequestException as exc:
LOGGER.warning("Unable to fetch user profile", exc=exc)
return None
else:
return response.json().get("user", {})
class PlexOAuth2Callback(OAuthCallback):
"""Plex OAuth2 Callback"""
client_class = PlexOAuthClient
def get_user_id(
self, source: UserOAuthSourceConnection, info: dict[str, Any]
) -> Optional[str]:
return info.get("uuid")
def get_user_enroll_context(
self,
source: OAuthSource,
access: UserOAuthSourceConnection,
info: dict[str, Any],
) -> dict[str, Any]:
return {
"username": info.get("username"),
"email": info.get("email"),
"name": info.get("title"),
}
@MANAGER.type()
class PlexType(SourceType):
"""Plex Type definition"""
redirect_view = PlexRedirect
callback_view = PlexOAuth2Callback
name = "Plex"
slug = "plex"
authorization_url = ""
access_token_url = "" # nosec
profile_url = ""

View File

@ -209,9 +209,9 @@ class OAuthCallback(OAuthClientMixin, View):
)
return redirect(
reverse(
"authentik_sources_oauth:oauth-client-user",
kwargs={"source_slug": self.source.slug},
"authentik_core:if-admin",
)
+ f"#/user;page-{self.source.slug}"
)
def handle_enroll(

View File

@ -21,6 +21,6 @@ class DispatcherView(View):
if not slug:
raise Http404
source = get_object_or_404(OAuthSource, slug=slug)
view = MANAGER.find(source, kind=RequestKind(self.kind))
view = MANAGER.find(source.provider_type, kind=RequestKind(self.kind))
LOGGER.debug("dispatching OAuth2 request to", view=view, kind=self.kind)
return view.as_view()(*args, **kwargs)

View File

@ -63,6 +63,7 @@ class EmailStageViewSet(ModelViewSet):
"name": value,
"description": label,
"component": "",
"model_name": "",
}
)
return Response(TypeCreateSerializer(choices, many=True).data)

View File

@ -4,6 +4,7 @@ version: '3.2'
services:
postgresql:
image: postgres:12
restart: unless-stopped
volumes:
- database:/var/lib/postgresql/data
networks:
@ -19,7 +20,8 @@ services:
networks:
- internal
server:
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.1}
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.3}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
@ -46,7 +48,8 @@ services:
env_file:
- .env
worker:
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.1}
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.3}
restart: unless-stopped
command: worker
networks:
- internal
@ -65,7 +68,8 @@ services:
env_file:
- .env
static:
image: ${AUTHENTIK_IMAGE_STATIC:-beryju/authentik-static}:${AUTHENTIK_TAG:-2021.4.1}
image: ${AUTHENTIK_IMAGE_STATIC:-beryju/authentik-static}:${AUTHENTIK_TAG:-2021.4.3}
restart: unless-stopped
networks:
- internal
labels:
@ -74,13 +78,14 @@ services:
traefik.http.routers.static-router.rule: PathPrefix(`/static`, `/if`, `/media`, `/robots.txt`, `/favicon.ico`)
traefik.http.routers.static-router.tls: 'true'
traefik.http.routers.static-router.service: static-service
traefik.http.services.static-service.loadbalancer.healthcheck.path: /-/health/ready/
traefik.http.services.static-service.loadbalancer.healthcheck.path: /
traefik.http.services.static-service.loadbalancer.healthcheck.interval: 30s
traefik.http.services.static-service.loadbalancer.server.port: '80'
volumes:
- ./media:/usr/share/nginx/html/media
traefik:
image: traefik:2.3
restart: unless-stopped
command:
- "--log.format=json"
- "--api.insecure=true"

View File

@ -4,7 +4,7 @@ name: authentik
home: https://goauthentik.io
sources:
- https://github.com/BeryJu/authentik
version: "2021.4.1"
version: "2021.4.3"
icon: https://raw.githubusercontent.com/BeryJu/authentik/master/web/icons/icon.svg
dependencies:
- name: postgresql

View File

@ -4,12 +4,12 @@
|-----------------------------------|-------------------------|-------------|
| image.name | beryju/authentik | Image used to run the authentik server and worker |
| image.name_static | beryju/authentik-static | Image used to run the authentik static server (CSS and JS Files) |
| image.tag | 2021.4.1 | Image tag |
| image.tag | 2021.4.3 | Image tag |
| image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments |
| serverReplicas | 1 | Replicas for the Server deployment |
| workerReplicas | 1 | Replicas for the Worker deployment |
| kubernetesIntegration | true | Enable/disable the Kubernetes integration for authentik. This will create a service account for authentik to create and update outposts in authentik |
| config.secretKey | | Secret key used to sign session cookies, generate with `pwgen 50 1` for example. |
| config.secretKey | | Secret key used to sign session cookies, generate with `pwgen 50 1` or `openssl rand -base64 36` for example. |
| config.errorReporting.enabled | false | Enable/disable error reporting |
| config.errorReporting.environment | customer | Environment sent with the error reporting |
| config.errorReporting.sendPii | false | Whether to send Personally-identifiable data with the error reporting |
@ -22,6 +22,11 @@
| config.email.use_ssl | false | Enable SSL |
| config.email.timeout | 10 | SMTP Timeout |
| config.email.from | authentik@localhost | Email address authentik will send from, should have a correct @domain |
| pvc.mode | ReadWriteMany | Mode that the PVCs are created in (uploads and GeoIP, if enabled) |
| pvc.uploadsSize | 5Gi | Size for the uploads PVC |
| pvc.uploadsStorageClass | null | Storage class for the uploads PVC (default: use default storage class) |
| pvc.geoIpSize | 1Gi | Size for the GeoIP PVC |
| pvc.geoIpStorageClass | null | Storage class for the GeoIP PVC (default: use default storage class) |
| geoip.enabled | false | Optionally enable GeoIP |
| geoip.accountId | | GeoIP MaxMind Account ID |
| geoip.licenseKey | | GeoIP MaxMind License key |

View File

@ -10,8 +10,9 @@ metadata:
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
accessModes:
- ReadWriteMany
- {{ .Values.pvc.mode }}
storageClassName: {{ .Values.pvc.geoIpStorageClass }}
resources:
requests:
storage: 1Gi
storage: {{ .Values.pvc.geoIpSize }}
{{- end }}

View File

@ -9,7 +9,8 @@ metadata:
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
accessModes:
- ReadWriteMany
- {{ .Values.pvc.mode }}
storageClassName: {{ .Values.pvc.uploadsStorageClass }}
resources:
requests:
storage: 5Gi
storage: {{ .Values.pvc.uploadsSize }}

View File

@ -43,29 +43,6 @@ spec:
values:
- web
topologyKey: "kubernetes.io/hostname"
initContainers:
- name: authentik-database-migrations
image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
args: [migrate]
envFrom:
- configMapRef:
name: {{ include "authentik.fullname" . }}-config
prefix: AUTHENTIK_
- secretRef:
name: {{ include "authentik.fullname" . }}-secret-key
prefix: AUTHENTIK_
env:
- name: AUTHENTIK_REDIS__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-redis"
key: redis-password
- name: AUTHENTIK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-postgresql"
key: postgresql-password
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"

View File

@ -5,7 +5,7 @@ image:
name: beryju/authentik
name_static: beryju/authentik-static
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
tag: 2021.4.1
tag: 2021.4.3
pullPolicy: IfNotPresent
serverReplicas: 1
@ -15,7 +15,14 @@ workerReplicas: 1
kubernetesIntegration: true
monitoring:
enabled: true
enabled: false
pvc:
mode: ReadWriteMany
uploadsSize: 5Gi
uploadsStorageClass: null
geoIpSize: 1Gi
geoIpStorageClass: null
config:
# Optionally specify fixed secret_key, otherwise generated automatically

View File

@ -2,13 +2,13 @@
python -m lifecycle.wait_for_db
printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
if [[ "$1" == "server" ]]; then
python -m lifecycle.migrate
gunicorn -c /lifecycle/gunicorn.conf.py authentik.root.asgi:application
elif [[ "$1" == "worker" ]]; then
celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
elif [[ "$1" == "migrate" ]]; then
# Run system migrations first, run normal migrations after
printf "DEPERECATED: database migrations are now executed automatically on startup."
python -m lifecycle.migrate
python -m manage migrate
elif [[ "$1" == "backup" ]]; then
python -m manage dbbackup --clean
elif [[ "$1" == "restore" ]]; then

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
"""System Migration handler"""
import os
from importlib.util import module_from_spec, spec_from_file_location
from inspect import getmembers, isclass
from pathlib import Path
@ -11,6 +12,7 @@ from structlog.stdlib import get_logger
from authentik.lib.config import CONFIG
LOGGER = get_logger()
ADV_LOCK_UID = 1000
class BaseMigration:
@ -40,18 +42,36 @@ if __name__ == "__main__":
host=CONFIG.y("postgresql.host"),
)
curr = conn.cursor()
# lock an advisory lock to prevent multiple instances from migrating at once
LOGGER.info("waiting to acquire database lock")
curr.execute("SELECT pg_advisory_lock(%s)", (ADV_LOCK_UID,))
try:
for migration in (
Path(__file__).parent.absolute().glob("system_migrations/*.py")
):
spec = spec_from_file_location("lifecycle.system_migrations", migration)
mod = module_from_spec(spec)
# pyright: reportGeneralTypeIssues=false
spec.loader.exec_module(mod)
for migration in Path(__file__).parent.absolute().glob("system_migrations/*.py"):
spec = spec_from_file_location("lifecycle.system_migrations", migration)
mod = module_from_spec(spec)
# pyright: reportGeneralTypeIssues=false
spec.loader.exec_module(mod)
for name, sub in getmembers(mod, isclass):
if name != "Migration":
continue
migration = sub(curr, conn)
if migration.needs_migration():
LOGGER.info("Migration needs to be applied", migration=sub)
migration.run()
LOGGER.info("Migration finished applying", migration=sub)
for name, sub in getmembers(mod, isclass):
if name != "Migration":
continue
migration = sub(curr, conn)
if migration.needs_migration():
LOGGER.info("Migration needs to be applied", migration=sub)
migration.run()
LOGGER.info("Migration finished applying", migration=sub)
LOGGER.info("applying django migrations")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(["", "migrate"])
finally:
curr.execute("SELECT pg_advisory_unlock(%s)", (ADV_LOCK_UID,))

View File

@ -18,7 +18,7 @@ stages:
steps:
- task: GoTool@0
inputs:
version: '1.15'
version: '1.16.3'
- task: CmdLine@2
inputs:
script: |
@ -40,11 +40,7 @@ stages:
steps:
- task: GoTool@0
inputs:
version: '1.15'
- task: Go@0
inputs:
command: 'get'
arguments: '-u golang.org/x/lint/golint'
version: '1.16.3'
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
@ -53,7 +49,7 @@ stages:
- task: CmdLine@2
inputs:
script: |
$(go list -f {{.Target}} golang.org/x/lint/golint) ./...
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.39.0 golangci-lint run -v --timeout 200s
workingDirectory: 'outpost/'
- stage: proxy_build_go
jobs:
@ -63,7 +59,7 @@ stages:
steps:
- task: GoTool@0
inputs:
version: '1.15'
version: '1.16.3'
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
@ -82,7 +78,7 @@ stages:
steps:
- task: GoTool@0
inputs:
version: '1.15'
version: '1.16.3'
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'

View File

@ -52,13 +52,14 @@ func main() {
ac.Server = proxy.NewServer(ac)
ac.Start()
err = ac.Start()
if err != nil {
log.WithError(err).Panic("Failed to run server")
}
for {
select {
case <-interrupt:
ac.Shutdown()
os.Exit(0)
}
<-interrupt
ac.Shutdown()
os.Exit(0)
}
}

View File

@ -8,12 +8,12 @@ require (
github.com/getsentry/sentry-go v0.10.0
github.com/go-openapi/analysis v0.20.1 // indirect
github.com/go-openapi/errors v0.20.0
github.com/go-openapi/runtime v0.19.27
github.com/go-openapi/runtime v0.19.28
github.com/go-openapi/strfmt v0.20.1
github.com/go-openapi/swag v0.19.15
github.com/go-openapi/validate v0.20.2
github.com/go-redis/redis/v7 v7.4.0 // indirect
github.com/go-swagger/go-swagger v0.27.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/websocket v1.4.2
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/justinas/alice v1.2.0
@ -23,6 +23,7 @@ require (
github.com/oauth2-proxy/oauth2-proxy v0.0.0-20200831161845-e4e5580852dc
github.com/pelletier/go-toml v1.9.0 // indirect
github.com/pkg/errors v0.9.1
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
github.com/recws-org/recws v1.3.1
github.com/sirupsen/logrus v1.8.1
github.com/spf13/afero v1.6.0 // indirect
@ -30,10 +31,11 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.1 // indirect
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 // indirect
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d // indirect
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 // indirect
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.31.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
)

View File

@ -102,7 +102,6 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -124,8 +123,6 @@ github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE=
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -157,7 +154,6 @@ github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9sn
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ=
github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk=
github.com/go-openapi/analysis v0.20.0 h1:UN09o0kNhleunxW7LR+KnltD0YrJ8FF03pSqvAN3Vro=
github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
github.com/go-openapi/analysis v0.20.1 h1:zdVbw8yoD4SWZeq+cWdGgquaB0W4VrsJvDJHJND/Ktc=
github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
@ -171,8 +167,6 @@ github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.0 h1:Sxpo9PjEHDzhs3FbnGNonvDgWcMW2U7wGTcDDSFSceM=
github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
@ -202,8 +196,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.19.27 h1:4zrQCJoP7rqNCUaApDv1MdPkaa5TuPfO05Lq5WLhX9I=
github.com/go-openapi/runtime v0.19.27/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
github.com/go-openapi/runtime v0.19.28 h1:9lYu6axek8LJrVkMVViVirRcpoaCxXX7+sSvmizGVnA=
github.com/go-openapi/runtime v0.19.28/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
@ -252,9 +246,6 @@ github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRf
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-swagger/go-swagger v0.27.0 h1:K7+nkBuf4oS1jTBrdvWqYFpqD69V5CN8HamZzCDDhAI=
github.com/go-swagger/go-swagger v0.27.0/go.mod h1:WodZVysInJilkW7e6IRw+dZGp5yW6rlMFZ4cb+THl9A=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@ -310,8 +301,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -329,8 +318,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -352,8 +341,6 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@ -392,8 +379,6 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
@ -521,8 +506,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0=
github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI=
@ -538,8 +521,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e h1:BLqxdwZ6j771IpSCRx7s/GJjXHUE00Hmu7/YegCGdzA=
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac h1:jWKYCNlX4J5s8M0nHYkh7Y7c9gRVDEb3mq51j5J0F5M=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -559,7 +540,6 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
@ -586,7 +566,6 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@ -595,7 +574,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -613,8 +591,6 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@ -649,7 +625,6 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v0.0.0-20191213034115-f46add6fdb5c/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox0hTHlnpkcOTuFIDQpZ1IN8rKKhX0=
@ -690,8 +665,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -724,8 +697,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -766,23 +737,18 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5 h1:zuP3axpB9rV3xH0EA7n3/gCrNPZm2SRl0l4mVH2BRj4=
golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d h1:BgJvlyh+UqCUaPlscHJ+PN8GcpfrFdr7NHjd1JL0+Gs=
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 h1:D7nTwh4J0i+5mW4Zjzn5omvlr6YBcWywE6KOcatyNxY=
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -794,7 +760,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -845,13 +810,9 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4=
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -859,7 +820,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -919,8 +879,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1004,7 +962,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=

View File

@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"net/url"
"os"
"time"
"github.com/go-openapi/runtime"
@ -39,8 +40,8 @@ type APIController struct {
}
// NewAPIController initialise new API Controller instance from URL and API token
func NewAPIController(pbURL url.URL, token string) *APIController {
transport := httptransport.New(pbURL.Host, client.DefaultBasePath, []string{pbURL.Scheme})
func NewAPIController(akURL url.URL, token string) *APIController {
transport := httptransport.New(akURL.Host, client.DefaultBasePath, []string{akURL.Scheme})
transport.Transport = SetUserAgent(getTLSTransport(), fmt.Sprintf("authentik-proxy@%s", pkg.VERSION))
// create the transport
@ -53,10 +54,11 @@ func NewAPIController(pbURL url.URL, token string) *APIController {
// Because we don't know the outpost UUID, we simply do a list and pick the first
// The service account this token belongs to should only have access to a single outpost
outposts, err := apiClient.Outposts.OutpostsOutpostsList(outposts.NewOutpostsOutpostsListParams(), auth)
outposts, err := apiClient.Outposts.OutpostsInstancesList(outposts.NewOutpostsInstancesListParams(), auth)
if err != nil {
log.WithError(err).Panic("Failed to fetch configuration")
log.WithError(err).Error("Failed to fetch configuration")
os.Exit(1)
}
outpost := outposts.Payload.Results[0]
doGlobalSetup(outpost.Config.(map[string]interface{}))
@ -73,7 +75,7 @@ func NewAPIController(pbURL url.URL, token string) *APIController {
lastBundleHash: "",
}
ac.logger.Debugf("HA Reload offset: %s", ac.reloadOffset)
ac.initWS(pbURL, outpost.Pk)
ac.initWS(akURL, outpost.Pk)
return ac
}
@ -96,7 +98,10 @@ func (a *APIController) Start() error {
a.startWSHealth()
}()
go func() {
a.Server.Start()
err := a.Server.Start()
if err != nil {
panic(err)
}
}()
return nil
}

View File

@ -64,7 +64,6 @@ func (ac *APIController) Shutdown() {
ac.logger.Println("write close:", err)
return
}
return
}
func (ac *APIController) startWSHandler() {
@ -92,7 +91,8 @@ func (ac *APIController) startWSHandler() {
}
func (ac *APIController) startWSHealth() {
for ; true; <-time.Tick(time.Second * 10) {
ticker := time.NewTicker(time.Second * 10)
for ; true; <-ticker.C {
if !ac.wsConn.IsConnected() {
continue
}

View File

@ -38,7 +38,11 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
return nil
}
providerOpts := &options.Options{}
copier.Copy(&providerOpts, getCommonOptions())
err = copier.Copy(&providerOpts, getCommonOptions())
if err != nil {
log.WithError(err).Warning("Failed to copy options, skipping provider")
return nil
}
providerOpts.ClientID = provider.ClientID
providerOpts.ClientSecret = provider.ClientSecret
@ -62,7 +66,7 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
ID: "default",
URI: *provider.InternalHost,
Path: "/",
InsecureSkipTLSVerify: *&provider.InternalHostSslValidation,
InsecureSkipTLSVerify: provider.InternalHostSslValidation,
},
}
@ -85,7 +89,7 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
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 {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to parse certificate")
return providerOpts
@ -135,7 +139,7 @@ func (pb *providerBundle) Build(provider *models.ProxyOutpostConfig) {
os.Exit(1)
}
if *&provider.BasicAuthEnabled {
if provider.BasicAuthEnabled {
oauthproxy.SetBasicAuth = true
oauthproxy.BasicAuthUserAttribute = provider.BasicAuthUserAttribute
oauthproxy.BasicAuthPasswordAttribute = provider.BasicAuthPasswordAttribute

View File

@ -1,3 +1,3 @@
package pkg
const VERSION = "2021.4.1"
const VERSION = "2021.4.3"

View File

@ -1152,6 +1152,9 @@ paths:
description: Page Size
required: false
type: integer
- name: superuser_full_list
in: query
type: boolean
responses:
'200':
description: ''
@ -2237,15 +2240,15 @@ paths:
description: ''
schema:
$ref: '#/definitions/Link'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- core
parameters:
@ -3664,15 +3667,15 @@ paths:
description: ''
schema:
$ref: '#/definitions/Challenge'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- flows
post:
@ -4366,6 +4369,281 @@ paths:
description: A unique integer value identifying this OAuth2 Token.
required: true
type: integer
/outposts/instances/:
get:
operationId: outposts_instances_list
description: Outpost Viewset
parameters:
- name: providers__isnull
in: query
description: ''
required: false
type: string
- name: ordering
in: query
description: Which field to use when ordering the results.
required: false
type: string
- name: search
in: query
description: A search term.
required: false
type: string
- name: page
in: query
description: Page Index
required: false
type: integer
- name: page_size
in: query
description: Page Size
required: false
type: integer
responses:
'200':
description: ''
schema:
required:
- results
- pagination
type: object
properties:
pagination:
required:
- next
- previous
- count
- current
- total_pages
- start_index
- end_index
type: object
properties:
next:
type: number
previous:
type: number
count:
type: number
current:
type: number
total_pages:
type: number
start_index:
type: number
end_index:
type: number
results:
type: array
items:
$ref: '#/definitions/Outpost'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- outposts
post:
operationId: outposts_instances_create
description: Outpost Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/Outpost'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/Outpost'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- outposts
parameters: []
/outposts/instances/default_settings/:
get:
operationId: outposts_instances_default_settings
description: Global default outpost config
parameters:
- name: providers__isnull
in: query
description: ''
required: false
type: string
- name: ordering
in: query
description: Which field to use when ordering the results.
required: false
type: string
- name: search
in: query
description: A search term.
required: false
type: string
- name: page
in: query
description: Page Index
required: false
type: integer
- name: page_size
in: query
description: Page Size
required: false
type: integer
responses:
'200':
description: ''
schema:
$ref: '#/definitions/OutpostDefaultConfig'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- outposts
parameters: []
/outposts/instances/{uuid}/:
get:
operationId: outposts_instances_read
description: Outpost Viewset
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/Outpost'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- outposts
put:
operationId: outposts_instances_update
description: Outpost Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/Outpost'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/Outpost'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- outposts
patch:
operationId: outposts_instances_partial_update
description: Outpost Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/Outpost'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/Outpost'
'400':
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- outposts
delete:
operationId: outposts_instances_delete
description: Outpost Viewset
parameters: []
responses:
'204':
description: ''
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- outposts
parameters:
- name: uuid
in: path
description: A UUID string identifying this outpost.
required: true
type: string
format: uuid
/outposts/instances/{uuid}/health/:
get:
operationId: outposts_instances_health
description: Get outposts current health
parameters: []
responses:
'200':
description: ''
schema:
type: array
items:
$ref: '#/definitions/OutpostHealth'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- outposts
parameters:
- name: uuid
in: path
description: A UUID string identifying this outpost.
required: true
type: string
format: uuid
/outposts/outposts/:
get:
operationId: outposts_outposts_list
@ -7671,6 +7949,9 @@ paths:
required: true
schema:
$ref: '#/definitions/PolicyTest'
- name: format_result
in: query
type: boolean
responses:
'200':
description: ''
@ -10265,7 +10546,7 @@ paths:
schema:
type: array
items:
$ref: '#/definitions/UserSetting'
$ref: '#/definitions/StageUserSetting'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
@ -14771,6 +15052,7 @@ definitions:
- name
- description
- component
- model_name
type: object
properties:
name:
@ -14785,6 +15067,10 @@ definitions:
title: Component
type: string
minLength: 1
model_name:
title: Model name
type: string
minLength: 1
EventTopPerUser:
required:
- application
@ -16963,9 +17249,6 @@ definitions:
- name
- slug
- provider_type
- authorization_url
- access_token_url
- profile_url
- consumer_key
- consumer_secret
type: object
@ -17032,24 +17315,29 @@ definitions:
for OAuth 1.
type: string
maxLength: 255
minLength: 1
x-nullable: true
authorization_url:
title: Authorization URL
description: URL the user is redirect to to conest the flow.
type: string
maxLength: 255
minLength: 1
x-nullable: true
access_token_url:
title: Access Token URL
description: URL used by authentik to retrive tokens.
type: string
maxLength: 255
minLength: 1
x-nullable: true
profile_url:
title: Profile URL
description: URL used by authentik to get user information.
type: string
maxLength: 255
minLength: 1
x-nullable: true
consumer_key:
title: Consumer key
type: string
@ -17222,6 +17510,28 @@ definitions:
\ log out manually. (Format: hours=1;minutes=2;seconds=3)."
type: string
minLength: 1
StageUserSetting:
required:
- object_uid
- component
- title
type: object
properties:
object_uid:
title: Object uid
type: string
minLength: 1
component:
title: Component
type: string
minLength: 1
title:
title: Title
type: string
minLength: 1
configure_flow:
title: Configure flow
type: boolean
AuthenticatorStaticStage:
required:
- name

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title/><path d="M11.643 0H4.68l7.679 12L4.68 24h6.963l7.677-12-7.677-12"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@ -81,7 +81,7 @@ http {
location /static/ {
expires 31d;
add_header Cache-Control "public, no-transform";
add_header X-authentik-version "2021.4.1";
add_header X-authentik-version "2021.4.3";
add_header Vary X-authentik-version;
}

12
web/package-lock.json generated
View File

@ -1956,9 +1956,9 @@
}
},
"@types/codemirror": {
"version": "0.0.108",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz",
"integrity": "sha512-3FGFcus0P7C2UOGCNUVENqObEb4SFk+S8Dnxq7K6aIsLVs/vDtlangl3PEO0ykaKXyK56swVF6Nho7VsA44uhw==",
"version": "0.0.109",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.109.tgz",
"integrity": "sha512-cSdiHeeLjvGn649lRTNeYrVCDOgDrtP+bDDSFDd1TF+i0jKGPDRozno2NOJ9lTniso+taiv4kiVS8dgM8Jm5lg==",
"requires": {
"@types/tern": "*"
}
@ -2647,9 +2647,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"chart.js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.1.0.tgz",
"integrity": "sha512-bKJi2VbC4fqZXlLbK7LKVvmG9crjoG9anfp96utZLyIGPuCx+YN+5/HDXy98QGt3lf74T8gKUPISUZL222tDJQ=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.1.1.tgz",
"integrity": "sha512-ghNJersc9VD9MECwa5bL8gqvCkndW6RSCicdEHL9lIriNtXwKawlSmwo+u6KNXLYT2+f24GdFPBoynKW3ke4MQ=="
},
"chartjs-adapter-moment": {
"version": "1.0.0",

View File

@ -53,14 +53,14 @@
"@sentry/browser": "^6.2.5",
"@sentry/tracing": "^6.2.5",
"@types/chart.js": "^2.9.32",
"@types/codemirror": "0.0.108",
"@types/codemirror": "0.0.109",
"@types/grecaptcha": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"authentik-api": "file:api",
"babel-plugin-macros": "^3.0.1",
"base64-js": "^1.5.1",
"chart.js": "^3.1.0",
"chart.js": "^3.1.1",
"chartjs-adapter-moment": "^1.0.0",
"codemirror": "^5.60.0",
"construct-style-sheets-polyfill": "^2.4.16",

View File

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

View File

@ -33,7 +33,12 @@ export class RouterOutlet extends LitElement {
css`
:host {
height: 100vh;
background-color: var(--ak-dark-background, var(--pf-c-page--BackgroundColor)) !important;
background-color: var(--pf-global--BackgroundColor--light-300) !important;
}
@media (prefers-color-scheme: dark) {
:host {
background-color: var(--ak-dark-background) !important;
}
}
*:first-child {
height: 100%;

View File

@ -162,11 +162,11 @@ export class FlowExecutor extends LitElement implements StageHost {
</div>
<footer class="pf-c-login__main-footer">
<ul class="pf-c-login__main-footer-links">
<li class="pf-c-login__main-footer-links-item">
<a class="pf-c-button pf-m-primary pf-m-block" href="/">
${t`Return`}
</a>
</li>
<li class="pf-c-login__main-footer-links-item">
<a class="pf-c-button pf-m-primary pf-m-block" href="/">
${t`Return`}
</a>
</li>
</ul>
</footer>`
};

View File

@ -68,7 +68,7 @@ msgstr "API request failed"
msgid "Access Key"
msgstr "Access Key"
#: src/pages/sources/oauth/OAuthSourceForm.ts:72
#: src/pages/sources/oauth/OAuthSourceForm.ts:73
msgid "Access token URL"
msgstr "Access token URL"
@ -79,13 +79,13 @@ msgstr "Access token URL"
msgid "Action"
msgstr "Action"
#: src/pages/groups/MemberSelectModal.ts:45
#: src/pages/groups/MemberSelectModal.ts:46
#: src/pages/users/UserListPage.ts:51
#: src/pages/users/UserViewPage.ts:116
msgid "Active"
msgstr "Active"
#: src/pages/groups/MemberSelectModal.ts:82
#: src/pages/groups/MemberSelectModal.ts:83
msgid "Add"
msgstr "Add"
@ -105,7 +105,7 @@ msgstr "Additional group DN, prepended to the Base DN."
msgid "Additional user DN, prepended to the Base DN."
msgstr "Additional user DN, prepended to the Base DN."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:128
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:131
#: src/pages/providers/proxy/ProxyProviderForm.ts:128
#: src/pages/providers/saml/SAMLProviderForm.ts:117
#: src/pages/sources/saml/SAMLSourceForm.ts:134
@ -125,7 +125,7 @@ msgstr "Affected model:"
msgid "Alert"
msgstr "Alert"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152
msgid "Algorithm used to sign the JWT Tokens."
msgstr "Algorithm used to sign the JWT Tokens."
@ -168,12 +168,12 @@ msgstr "App"
#: src/elements/user/UserConsentList.ts:29
#: src/pages/admin-overview/TopApplicationsTable.ts:42
#: src/pages/applications/ApplicationListPage.ts:104
#: src/pages/applications/ApplicationListPage.ts:105
#: src/pages/providers/ProviderListPage.ts:53
msgid "Application"
msgstr "Application"
#: src/pages/applications/ApplicationListPage.ts:68
#: src/pages/applications/ApplicationListPage.ts:69
msgid "Application Icon"
msgstr "Application Icon"
@ -220,19 +220,19 @@ msgstr "Are you sure you want to delete {0} {objName} ?"
msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "Are you sure you want to update {0} \"{1}\"?"
#: src/pages/providers/saml/SAMLProviderForm.ts:202
#: src/pages/providers/saml/SAMLProviderForm.ts:208
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts:191
#: src/pages/providers/saml/SAMLProviderForm.ts:197
msgid "Assertion valid not before"
msgstr "Assertion valid not before"
#: src/pages/providers/saml/SAMLProviderForm.ts:195
#: src/pages/providers/saml/SAMLProviderForm.ts:201
msgid "Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/providers/saml/SAMLProviderForm.ts:198
#: src/pages/providers/saml/SAMLProviderForm.ts:204
msgid "Assertion valid not on or after"
msgstr "Assertion valid not on or after"
@ -259,8 +259,8 @@ msgstr "Attempted to log in as {0}"
msgid "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded."
msgstr "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded."
#: src/pages/groups/GroupForm.ts:134
#: src/pages/stages/invitation/InvitationForm.ts:51
#: src/pages/groups/GroupForm.ts:135
#: src/pages/stages/invitation/InvitationForm.ts:52
#: src/pages/users/UserForm.ts:77
msgid "Attributes"
msgstr "Attributes"
@ -274,13 +274,13 @@ msgstr "Audience"
msgid "Authentication"
msgstr "Authentication"
#: src/pages/sources/oauth/OAuthSourceForm.ts:165
#: src/pages/sources/oauth/OAuthSourceForm.ts:189
#: src/pages/sources/saml/SAMLSourceForm.ts:245
msgid "Authentication flow"
msgstr "Authentication flow"
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts:63
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:29
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:33
msgid "Authenticator"
msgstr "Authenticator"
@ -292,7 +292,7 @@ msgstr "Authorization"
msgid "Authorization Code"
msgstr "Authorization Code"
#: src/pages/sources/oauth/OAuthSourceForm.ts:65
#: src/pages/sources/oauth/OAuthSourceForm.ts:66
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:95
msgid "Authorization URL"
msgstr "Authorization URL"
@ -342,19 +342,19 @@ msgstr "Backup status"
msgid "Base DN"
msgstr "Base DN"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:195
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204
msgid "Based on the Hashed User ID"
msgstr "Based on the Hashed User ID"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:201
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:210
msgid "Based on the User's Email. This is recommended over the UPN method."
msgstr "Based on the User's Email. This is recommended over the UPN method."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213
msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
msgstr "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:198
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207
msgid "Based on the username"
msgstr "Based on the username"
@ -416,7 +416,7 @@ msgstr "Can be in the format of 'unix://' when connecting to a local docker daem
#: src/elements/forms/ConfirmationForm.ts:75
#: src/elements/forms/DeleteForm.ts:86
#: src/elements/forms/ModalForm.ts:71
#: src/pages/groups/MemberSelectModal.ts:89
#: src/pages/groups/MemberSelectModal.ts:90
#: src/pages/users/UserActiveForm.ts:73
msgid "Cancel"
msgstr "Cancel"
@ -588,15 +588,15 @@ msgstr "Configuration"
msgid "Configuration flow"
msgstr "Configuration flow"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:103
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:106
msgid "Configure WebAuthn"
msgstr "Configure WebAuthn"
#: src/pages/providers/saml/SAMLProviderForm.ts:187
#: src/pages/providers/saml/SAMLProviderForm.ts:193
msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
msgstr "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:233
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:242
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr "Configure how the issuer field of the ID Token should be filled."
@ -604,15 +604,15 @@ msgstr "Configure how the issuer field of the ID Token should be filled."
msgid "Configure settings relevant to your user profile."
msgstr "Configure settings relevant to your user profile."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:208
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:47
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:43
msgid "Connect"
msgstr "Connect"
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:34
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:30
msgid "Connected."
msgstr "Connected."
@ -649,11 +649,11 @@ msgstr "Consider Objects matching this filter to be Groups."
msgid "Consider Objects matching this filter to be Users."
msgstr "Consider Objects matching this filter to be Users."
#: src/pages/sources/oauth/OAuthSourceForm.ts:124
#: src/pages/sources/oauth/OAuthSourceForm.ts:126
msgid "Consumer key"
msgstr "Consumer key"
#: src/pages/sources/oauth/OAuthSourceForm.ts:130
#: src/pages/sources/oauth/OAuthSourceForm.ts:132
msgid "Consumer secret"
msgstr "Consumer secret"
@ -695,8 +695,8 @@ msgid "Copy Key"
msgstr "Copy Key"
#: src/pages/applications/ApplicationForm.ts:120
#: src/pages/applications/ApplicationListPage.ts:120
#: src/pages/applications/ApplicationListPage.ts:128
#: src/pages/applications/ApplicationListPage.ts:121
#: src/pages/applications/ApplicationListPage.ts:129
#: src/pages/crypto/CertificateKeyPairListPage.ts:122
#: src/pages/crypto/CertificateKeyPairListPage.ts:130
#: src/pages/events/RuleListPage.ts:91
@ -737,12 +737,12 @@ msgstr "Copy Key"
#: src/pages/stages/prompt/PromptStageForm.ts:98
#: src/pages/user-settings/tokens/UserTokenList.ts:50
#: src/pages/user-settings/tokens/UserTokenList.ts:58
#: src/pages/users/UserListPage.ts:144
#: src/pages/users/UserListPage.ts:152
#: src/pages/users/UserListPage.ts:151
#: src/pages/users/UserListPage.ts:159
msgid "Create"
msgstr "Create"
#: src/pages/applications/ApplicationListPage.ts:123
#: src/pages/applications/ApplicationListPage.ts:124
#: src/pages/providers/RelatedApplicationButton.ts:30
msgid "Create Application"
msgstr "Create Application"
@ -808,7 +808,7 @@ msgstr "Create Stage binding"
msgid "Create Token"
msgstr "Create Token"
#: src/pages/users/UserListPage.ts:147
#: src/pages/users/UserListPage.ts:154
msgid "Create User"
msgstr "Create User"
@ -832,7 +832,7 @@ msgstr "Create {0}"
msgid "Created by"
msgstr "Created by"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:86
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:90
msgid "Created {0}"
msgstr "Created {0}"
@ -846,7 +846,7 @@ msgstr "Creation Date"
msgid "Customisation"
msgstr "Customisation"
#: src/pages/providers/saml/SAMLProviderForm.ts:249
#: src/pages/providers/saml/SAMLProviderForm.ts:255
#: src/pages/sources/saml/SAMLSourceForm.ts:212
msgid "DSA-SHA1"
msgstr "DSA-SHA1"
@ -868,7 +868,7 @@ msgid "Define how notifications are sent to users, like Email or Webhook."
msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/elements/forms/DeleteForm.ts:79
#: src/pages/applications/ApplicationListPage.ts:111
#: src/pages/applications/ApplicationListPage.ts:112
#: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86
@ -884,7 +884,7 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87
#: src/pages/tokens/TokenListPage.ts:68
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:36
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:40
#: src/pages/user-settings/tokens/UserTokenList.ts:125
#: src/pages/users/UserListPage.ts:115
msgid "Delete"
@ -963,11 +963,11 @@ msgstr "Determines how long a session lasts. Default of 0 seconds means that the
msgid "Device classes which can be used to authenticate."
msgstr "Device classes which can be used to authenticate."
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:59
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:63
msgid "Device name"
msgstr "Device name"
#: src/pages/providers/saml/SAMLProviderForm.ts:213
#: src/pages/providers/saml/SAMLProviderForm.ts:219
#: src/pages/sources/saml/SAMLSourceForm.ts:176
msgid "Digest algorithm"
msgstr "Digest algorithm"
@ -981,11 +981,11 @@ msgstr "Digits"
msgid "Disable"
msgstr "Disable"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:51
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:55
msgid "Disable Static Tokens"
msgstr "Disable Static Tokens"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:36
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:40
msgid "Disable Time-based OTP"
msgstr "Disable Time-based OTP"
@ -993,7 +993,7 @@ msgstr "Disable Time-based OTP"
msgid "Disabled"
msgstr "Disabled"
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:41
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:37
msgid "Disconnect"
msgstr "Disconnect"
@ -1010,11 +1010,11 @@ msgstr "Download"
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr "Dummy stage used for testing. Shows a simple continue button and always passes."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:235
msgid "Each provider has a different issuer, based on the application slug."
msgstr "Each provider has a different issuer, based on the application slug."
#: src/pages/applications/ApplicationListPage.ts:94
#: src/pages/applications/ApplicationListPage.ts:95
#: src/pages/applications/ApplicationViewPage.ts:91
#: src/pages/applications/ApplicationViewPage.ts:105
#: src/pages/crypto/CertificateKeyPairListPage.ts:74
@ -1096,18 +1096,18 @@ msgstr "Enable"
msgid "Enable StartTLS"
msgstr "Enable StartTLS"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:67
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:55
msgid "Enable Static Tokens"
msgstr "Enable Static Tokens"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:52
msgid "Enable Time-based OTP"
msgstr "Enable Time-based OTP"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:70
msgid "Enable TOTP"
msgstr "Enable TOTP"
#: src/pages/policies/BoundPoliciesList.ts:37
#: src/pages/policies/PolicyBindingForm.ts:198
#: src/pages/sources/ldap/LDAPSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:113
#: src/pages/sources/oauth/OAuthSourceForm.ts:115
#: src/pages/sources/saml/SAMLSourceForm.ts:69
msgid "Enabled"
msgstr "Enabled"
@ -1116,7 +1116,7 @@ msgstr "Enabled"
msgid "Enrollment"
msgstr "Enrollment"
#: src/pages/sources/oauth/OAuthSourceForm.ts:186
#: src/pages/sources/oauth/OAuthSourceForm.ts:210
#: src/pages/sources/saml/SAMLSourceForm.ts:266
#: src/pages/stages/identification/IdentificationStageForm.ts:107
msgid "Enrollment flow"
@ -1209,7 +1209,7 @@ msgstr "Execution logging"
#: src/elements/oauth/UserCodeList.ts:30
#: src/elements/oauth/UserRefreshList.ts:30
#: src/elements/user/UserConsentList.ts:30
#: src/pages/stages/invitation/InvitationForm.ts:45
#: src/pages/stages/invitation/InvitationForm.ts:46
msgid "Expires"
msgstr "Expires"
@ -1255,8 +1255,8 @@ msgid "Expression using Python."
msgstr "Expression using Python."
#: src/pages/applications/ApplicationListPage.ts:31
msgid "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML."
msgstr "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML."
msgid "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access."
msgstr "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access."
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:90
msgid "External Host"
@ -1328,17 +1328,17 @@ msgstr "Flow"
msgid "Flow Overview"
msgstr "Flow Overview"
#: src/pages/sources/oauth/OAuthSourceForm.ts:161
#: src/pages/sources/oauth/OAuthSourceForm.ts:185
#: src/pages/sources/saml/SAMLSourceForm.ts:220
msgid "Flow settings"
msgstr "Flow settings"
#: src/pages/sources/oauth/OAuthSourceForm.ts:183
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/saml/SAMLSourceForm.ts:263
msgid "Flow to use when authenticating existing users."
msgstr "Flow to use when authenticating existing users."
#: src/pages/sources/oauth/OAuthSourceForm.ts:204
#: src/pages/sources/oauth/OAuthSourceForm.ts:228
#: src/pages/sources/saml/SAMLSourceForm.ts:284
msgid "Flow to use when enrolling new users."
msgstr "Flow to use when enrolling new users."
@ -1451,7 +1451,7 @@ msgstr "Group {0}"
msgid "Groups"
msgstr "Groups"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149
msgid "HS256 (Symmetric Encryption)"
msgstr "HS256 (Symmetric Encryption)"
@ -1476,10 +1476,10 @@ msgid "Hide managed mappings"
msgstr "Hide managed mappings"
#: src/pages/events/RuleForm.ts:93
#: src/pages/groups/GroupForm.ts:131
#: src/pages/groups/GroupForm.ts:132
#: src/pages/outposts/OutpostForm.ts:98
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:169
#: src/pages/providers/saml/SAMLProviderForm.ts:171
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:178
#: src/pages/providers/saml/SAMLProviderForm.ts:177
#: src/pages/sources/ldap/LDAPSourceForm.ts:167
#: src/pages/sources/ldap/LDAPSourceForm.ts:193
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
@ -1531,7 +1531,7 @@ msgstr "If this flag is set, this Stage will jump to the next Stage when no Invi
msgid "If your authentik Instance is using a self-signed certificate, set this value."
msgstr "If your authentik Instance is using a self-signed certificate, set this value."
#: src/pages/users/UserListPage.ts:136
#: src/pages/users/UserListPage.ts:143
msgid "Impersonate"
msgstr "Impersonate"
@ -1552,11 +1552,11 @@ msgstr "Import certificates of external providers or create certificates to sign
msgid "In case you can't access any other method."
msgstr "In case you can't access any other method."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:218
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:227
msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
msgstr "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:215
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:224
msgid "Include claims in id_token"
msgstr "Include claims in id_token"
@ -1589,7 +1589,7 @@ msgstr "Invitations"
msgid "Is active"
msgstr "Is active"
#: src/pages/groups/GroupForm.ts:60
#: src/pages/groups/GroupForm.ts:62
msgid "Is superuser"
msgstr "Is superuser"
@ -1600,15 +1600,15 @@ msgstr "Is superuser"
msgid "Issuer"
msgstr "Issuer"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:221
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230
msgid "Issuer mode"
msgstr "Issuer mode"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:138
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:141
msgid "JWT Algorithm"
msgstr "JWT Algorithm"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:187
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:196
msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
msgstr "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
@ -1633,7 +1633,7 @@ msgstr "Label"
msgid "Label shown next to/above the prompt."
msgstr "Label shown next to/above the prompt."
#: src/pages/groups/MemberSelectModal.ts:46
#: src/pages/groups/MemberSelectModal.ts:47
#: src/pages/users/UserListPage.ts:52
#: src/pages/users/UserViewPage.ts:108
msgid "Last login"
@ -1680,6 +1680,7 @@ msgstr "Library"
#: src/flows/stages/identification/IdentificationStage.ts:134
#: src/flows/stages/password/PasswordStage.ts:31
#: src/flows/stages/prompt/PromptStage.ts:126
#: src/pages/applications/ApplicationViewPage.ts:43
#: src/pages/applications/ApplicationViewPage.ts:54
#: src/pages/user-settings/UserDetailsPage.ts:38
#: src/utils.ts:40
@ -1692,8 +1693,8 @@ msgstr "Loading"
#: src/pages/events/RuleForm.ts:90
#: src/pages/flows/StageBindingForm.ts:89
#: src/pages/flows/StageBindingForm.ts:106
#: src/pages/groups/GroupForm.ts:76
#: src/pages/groups/GroupForm.ts:127
#: src/pages/groups/GroupForm.ts:77
#: src/pages/groups/GroupForm.ts:128
#: src/pages/outposts/OutpostForm.ts:74
#: src/pages/outposts/OutpostForm.ts:96
#: src/pages/outposts/ServiceConnectionDockerForm.ts:87
@ -1706,21 +1707,21 @@ msgstr "Loading"
#: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:108
#: src/pages/property-mappings/PropertyMappingTestForm.ts:59
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:166
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:175
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:194
#: src/pages/providers/proxy/ProxyProviderForm.ts:92
#: src/pages/providers/proxy/ProxyProviderForm.ts:143
#: src/pages/providers/saml/SAMLProviderForm.ts:71
#: src/pages/providers/saml/SAMLProviderForm.ts:133
#: src/pages/providers/saml/SAMLProviderForm.ts:149
#: src/pages/providers/saml/SAMLProviderForm.ts:169
#: src/pages/providers/saml/SAMLProviderForm.ts:185
#: src/pages/providers/saml/SAMLProviderForm.ts:175
#: src/pages/providers/saml/SAMLProviderForm.ts:191
#: src/pages/providers/saml/SAMLProviderImportForm.ts:55
#: src/pages/sources/ldap/LDAPSourceForm.ts:164
#: src/pages/sources/ldap/LDAPSourceForm.ts:190
#: src/pages/sources/oauth/OAuthSourceForm.ts:153
#: src/pages/sources/oauth/OAuthSourceForm.ts:181
#: src/pages/sources/oauth/OAuthSourceForm.ts:202
#: src/pages/sources/oauth/OAuthSourceForm.ts:177
#: src/pages/sources/oauth/OAuthSourceForm.ts:205
#: src/pages/sources/oauth/OAuthSourceForm.ts:226
#: src/pages/sources/saml/SAMLSourceForm.ts:126
#: src/pages/sources/saml/SAMLSourceForm.ts:240
#: src/pages/sources/saml/SAMLSourceForm.ts:261
@ -1796,7 +1797,7 @@ msgstr "Matches an event against a set of criteria. If any of the configured val
msgid "Maximum age (in days)"
msgstr "Maximum age (in days)"
#: src/pages/groups/GroupForm.ts:80
#: src/pages/groups/GroupForm.ts:81
#: src/pages/groups/GroupListPage.ts:47
msgid "Members"
msgstr "Members"
@ -1845,7 +1846,7 @@ msgid "Monitor"
msgstr "Monitor"
#: src/pages/applications/ApplicationForm.ts:86
#: src/pages/applications/ApplicationListPage.ts:57
#: src/pages/applications/ApplicationListPage.ts:58
#: src/pages/crypto/CertificateKeyPairForm.ts:45
#: src/pages/crypto/CertificateKeyPairListPage.ts:51
#: src/pages/events/EventInfo.ts:51
@ -1856,9 +1857,9 @@ msgstr "Monitor"
#: src/pages/flows/BoundStagesList.ts:39
#: src/pages/flows/FlowForm.ts:81
#: src/pages/flows/FlowListPage.ts:47
#: src/pages/groups/GroupForm.ts:51
#: src/pages/groups/GroupForm.ts:53
#: src/pages/groups/GroupListPage.ts:45
#: src/pages/groups/MemberSelectModal.ts:44
#: src/pages/groups/MemberSelectModal.ts:45
#: src/pages/outposts/OutpostForm.ts:47
#: src/pages/outposts/OutpostListPage.ts:50
#: src/pages/outposts/ServiceConnectionDockerForm.ts:53
@ -1887,7 +1888,7 @@ msgstr "Monitor"
#: src/pages/sources/SourcesListPage.ts:51
#: src/pages/sources/ldap/LDAPSourceForm.ts:54
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:98
#: src/pages/sources/oauth/OAuthSourceForm.ts:100
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:54
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66
@ -1924,7 +1925,7 @@ msgstr "Name of the form field, also used to store the value."
msgid "NameID Policy"
msgstr "NameID Policy"
#: src/pages/providers/saml/SAMLProviderForm.ts:174
#: src/pages/providers/saml/SAMLProviderForm.ts:180
msgid "NameID Property Mapping"
msgstr "NameID Property Mapping"
@ -1939,7 +1940,7 @@ msgstr "New version available!"
#: src/pages/crypto/CertificateKeyPairListPage.ts:61
#: src/pages/groups/GroupListPage.ts:58
#: src/pages/groups/MemberSelectModal.ts:56
#: src/pages/groups/MemberSelectModal.ts:57
#: src/pages/outposts/ServiceConnectionListPage.ts:64
#: src/pages/policies/BoundPoliciesList.ts:118
#: src/pages/policies/PolicyTestForm.ts:38
@ -1996,6 +1997,10 @@ msgstr "No policies are currently bound to this object."
msgid "No policies cached. Users may experience slow response times."
msgstr "No policies cached. Users may experience slow response times."
#: src/pages/users/UserListPage.ts:135
msgid "No recovery flow is configured."
msgstr "No recovery flow is configured."
#: src/pages/flows/BoundStagesList.ts:114
msgid "No stages are currently bound to this flow."
msgstr "No stages are currently bound to this flow."
@ -2016,7 +2021,7 @@ msgstr "Not available"
msgid "Not configured action"
msgstr "Not configured action"
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:44
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:40
msgid "Not connected."
msgstr "Not connected."
@ -2110,7 +2115,7 @@ msgstr "Only fail the policy, don't invalidate user's password."
msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr "Only send notification once, for example when sending a webhook into a chat channel."
#: src/pages/applications/ApplicationListPage.ts:99
#: src/pages/applications/ApplicationListPage.ts:100
msgid "Open application"
msgstr "Open application"
@ -2130,7 +2135,7 @@ msgstr "Optional Private Key. If this is set, you can use this keypair for encry
msgid "Optional URL if the IDP supports Single-Logout."
msgstr "Optional URL if the IDP supports Single-Logout."
#: src/pages/stages/invitation/InvitationForm.ts:55
#: src/pages/stages/invitation/InvitationForm.ts:56
msgid "Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON."
msgstr "Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON."
@ -2204,7 +2209,7 @@ msgstr "Overview"
msgid "PEM-encoded Certificate data."
msgstr "PEM-encoded Certificate data."
#: src/pages/groups/GroupForm.ts:66
#: src/pages/groups/GroupForm.ts:68
#: src/pages/groups/GroupListPage.ts:46
msgid "Parent"
msgstr "Parent"
@ -2334,7 +2339,7 @@ msgstr "Private key available?"
msgid "Private key, acquired from https://www.google.com/recaptcha/intro/v3.html."
msgstr "Private key, acquired from https://www.google.com/recaptcha/intro/v3.html."
#: src/pages/sources/oauth/OAuthSourceForm.ts:79
#: src/pages/sources/oauth/OAuthSourceForm.ts:80
msgid "Profile URL"
msgstr "Profile URL"
@ -2376,7 +2381,7 @@ msgstr "Property mappings used to user creation."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81
#: src/pages/providers/proxy/ProxyProviderForm.ts:99
#: src/pages/providers/saml/SAMLProviderForm.ts:78
#: src/pages/sources/oauth/OAuthSourceForm.ts:120
#: src/pages/sources/oauth/OAuthSourceForm.ts:122
#: src/pages/sources/saml/SAMLSourceForm.ts:76
msgid "Protocol settings"
msgstr "Protocol settings"
@ -2388,18 +2393,17 @@ msgstr "Provide support for protocols like SAML and OAuth to assigned applicatio
#: src/elements/oauth/UserCodeList.ts:29
#: src/elements/oauth/UserRefreshList.ts:29
#: src/pages/applications/ApplicationForm.ts:100
#: src/pages/applications/ApplicationListPage.ts:59
#: src/pages/applications/ApplicationListPage.ts:60
#: src/pages/applications/ApplicationViewPage.ts:68
#: src/pages/providers/ProviderListPage.ts:34
msgid "Provider"
msgstr "Provider"
#: src/pages/applications/ApplicationListPage.ts:60
#: src/pages/applications/ApplicationListPage.ts:61
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:71
msgid "Provider Type"
msgstr "Provider Type"
#: src/pages/sources/oauth/OAuthSourceForm.ts:136
#: src/pages/sources/oauth/OAuthSourceForm.ts:138
msgid "Provider type"
msgstr "Provider type"
@ -2407,6 +2411,7 @@ msgstr "Provider type"
#: src/pages/admin-overview/AdminOverviewPage.ts:46
#: src/pages/outposts/OutpostForm.ts:82
#: src/pages/outposts/OutpostListPage.ts:51
#: src/pages/providers/ProviderListPage.ts:34
msgid "Providers"
msgstr "Providers"
@ -2430,30 +2435,30 @@ msgstr "Public key, acquired from https://www.google.com/recaptcha/intro/v3.html
msgid "Publisher"
msgstr "Publisher"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:143
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146
msgid "RS256 (Asymmetric Encryption)"
msgstr "RS256 (Asymmetric Encryption)"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:172
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:181
msgid "RSA Key"
msgstr "RSA Key"
#: src/pages/providers/saml/SAMLProviderForm.ts:237
#: src/pages/providers/saml/SAMLProviderForm.ts:243
#: src/pages/sources/saml/SAMLSourceForm.ts:200
msgid "RSA-SHA1"
msgstr "RSA-SHA1"
#: src/pages/providers/saml/SAMLProviderForm.ts:240
#: src/pages/providers/saml/SAMLProviderForm.ts:246
#: src/pages/sources/saml/SAMLSourceForm.ts:203
msgid "RSA-SHA256"
msgstr "RSA-SHA256"
#: src/pages/providers/saml/SAMLProviderForm.ts:243
#: src/pages/providers/saml/SAMLProviderForm.ts:249
#: src/pages/sources/saml/SAMLSourceForm.ts:206
msgid "RSA-SHA384"
msgstr "RSA-SHA384"
#: src/pages/providers/saml/SAMLProviderForm.ts:246
#: src/pages/providers/saml/SAMLProviderForm.ts:252
#: src/pages/sources/saml/SAMLSourceForm.ts:209
msgid "RSA-SHA512"
msgstr "RSA-SHA512"
@ -2478,11 +2483,14 @@ msgstr "Recovery keys"
msgid "Redirect"
msgstr "Redirect"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:119
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:107
msgid "Redirect URIs"
msgstr "Redirect URIs"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:119
msgid "Redirect URIs/Origins"
msgstr "Redirect URIs/Origins"
#: src/pages/sources/saml/SAMLSourceForm.ts:104
msgid "Redirect binding"
msgstr "Redirect binding"
@ -2525,7 +2533,7 @@ msgstr "Request"
msgid "Request has been denied."
msgstr "Request has been denied."
#: src/pages/sources/oauth/OAuthSourceForm.ts:86
#: src/pages/sources/oauth/OAuthSourceForm.ts:87
msgid "Request token URL"
msgstr "Request token URL"
@ -2538,7 +2546,7 @@ msgstr "Required"
msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
#: src/pages/users/UserListPage.ts:133
#: src/pages/users/UserListPage.ts:140
#: src/pages/users/UserViewPage.ts:165
msgid "Reset Password"
msgstr "Reset Password"
@ -2578,22 +2586,22 @@ msgstr "Return to device picker"
msgid "SAML Attribute Name"
msgstr "SAML Attribute Name"
#: src/pages/providers/saml/SAMLProviderForm.ts:218
#: src/pages/providers/saml/SAMLProviderForm.ts:224
#: src/pages/sources/saml/SAMLSourceForm.ts:181
msgid "SHA1"
msgstr "SHA1"
#: src/pages/providers/saml/SAMLProviderForm.ts:221
#: src/pages/providers/saml/SAMLProviderForm.ts:227
#: src/pages/sources/saml/SAMLSourceForm.ts:184
msgid "SHA256"
msgstr "SHA256"
#: src/pages/providers/saml/SAMLProviderForm.ts:224
#: src/pages/providers/saml/SAMLProviderForm.ts:230
#: src/pages/sources/saml/SAMLSourceForm.ts:187
msgid "SHA384"
msgstr "SHA384"
#: src/pages/providers/saml/SAMLProviderForm.ts:227
#: src/pages/providers/saml/SAMLProviderForm.ts:233
#: src/pages/sources/saml/SAMLSourceForm.ts:190
msgid "SHA512"
msgstr "SHA512"
@ -2624,7 +2632,7 @@ msgstr "SMTP Username"
msgid "SSO URL"
msgstr "SSO URL"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:229
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:238
msgid "Same identifier is used for all providers"
msgstr "Same identifier is used for all providers"
@ -2638,7 +2646,7 @@ msgstr "Scope which the client can specify to access these properties."
#: src/elements/oauth/UserCodeList.ts:31
#: src/elements/oauth/UserRefreshList.ts:31
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:155
msgid "Scopes"
msgstr "Scopes"
@ -2669,11 +2677,11 @@ msgstr "Select all rows"
msgid "Select an identification method."
msgstr "Select an identification method."
#: src/pages/groups/MemberSelectModal.ts:67
#: src/pages/groups/MemberSelectModal.ts:68
msgid "Select users to add"
msgstr "Select users to add"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:168
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:177
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."
@ -2734,11 +2742,11 @@ msgstr "Service connection"
msgid "Session duration"
msgstr "Session duration"
#: src/pages/providers/saml/SAMLProviderForm.ts:209
#: src/pages/providers/saml/SAMLProviderForm.ts:215
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts:205
#: src/pages/providers/saml/SAMLProviderForm.ts:211
msgid "Session valid not on or after"
msgstr "Session valid not on or after"
@ -2750,7 +2758,7 @@ msgstr "Set HTTP-Basic Authentication"
msgid "Set a custom HTTP-Basic Authentication header based on values from authentik."
msgstr "Set a custom HTTP-Basic Authentication header based on values from authentik."
#: src/pages/groups/GroupForm.ts:138
#: src/pages/groups/GroupForm.ts:139
#: src/pages/outposts/OutpostForm.ts:109
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts:73
#: src/pages/policies/PolicyTestForm.ts:78
@ -2779,7 +2787,7 @@ msgstr "Shown as the Title in Flow pages."
msgid "Sign up."
msgstr "Sign up."
#: src/pages/providers/saml/SAMLProviderForm.ts:232
#: src/pages/providers/saml/SAMLProviderForm.ts:238
#: src/pages/sources/saml/SAMLSourceForm.ts:195
msgid "Signature algorithm"
msgstr "Signature algorithm"
@ -2801,10 +2809,10 @@ msgid "Skip path regex"
msgstr "Skip path regex"
#: src/pages/applications/ApplicationForm.ts:93
#: src/pages/applications/ApplicationListPage.ts:58
#: src/pages/applications/ApplicationListPage.ts:59
#: src/pages/flows/FlowForm.ts:94
#: src/pages/sources/ldap/LDAPSourceForm.ts:60
#: src/pages/sources/oauth/OAuthSourceForm.ts:104
#: src/pages/sources/oauth/OAuthSourceForm.ts:106
#: src/pages/sources/saml/SAMLSourceForm.ts:60
msgid "Slug"
msgstr "Slug"
@ -2818,7 +2826,7 @@ msgstr "Something went wrong! Please try again later."
msgid "Source"
msgstr "Source"
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:21
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:18
msgid "Source {0}"
msgstr "Source {0}"
@ -2897,10 +2905,13 @@ msgid "State"
msgstr "State"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:104
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:77
msgid "Static Tokens"
msgstr "Static Tokens"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:62
msgid "Static tokens"
msgstr "Static tokens"
#: src/pages/stages/prompt/PromptForm.ts:75
msgid "Static: Static value, displayed as-is."
msgstr "Static: Static value, displayed as-is."
@ -2913,13 +2924,13 @@ msgstr "Statically deny the flow. To use this stage effectively, disable *Evalua
msgid "Status"
msgstr "Status"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:44
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:59
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:48
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:63
msgid "Status: Disabled"
msgstr "Status: Disabled"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:18
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:22
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:22
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:26
msgid "Status: Enabled"
msgstr "Status: Enabled"
@ -2931,7 +2942,7 @@ msgstr "Stop impersonation"
msgid "Subject"
msgstr "Subject"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:190
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:199
msgid "Subject mode"
msgstr "Subject mode"
@ -2972,11 +2983,11 @@ msgstr "Successfully created certificate-key pair."
msgid "Successfully created flow."
msgstr "Successfully created flow."
#: src/pages/groups/GroupForm.ts:44
#: src/pages/groups/GroupForm.ts:46
msgid "Successfully created group."
msgstr "Successfully created group."
#: src/pages/stages/invitation/InvitationForm.ts:38
#: src/pages/stages/invitation/InvitationForm.ts:39
msgid "Successfully created invitation."
msgstr "Successfully created invitation."
@ -3020,7 +3031,7 @@ msgid "Successfully created service-connection."
msgstr "Successfully created service-connection."
#: src/pages/sources/ldap/LDAPSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:50
#: src/pages/sources/oauth/OAuthSourceForm.ts:51
#: src/pages/sources/saml/SAMLSourceForm.ts:47
msgid "Successfully created source."
msgstr "Successfully created source."
@ -3100,7 +3111,7 @@ msgstr "Successfully updated certificate-key pair."
msgid "Successfully updated details."
msgstr "Successfully updated details."
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:50
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:54
msgid "Successfully updated device."
msgstr "Successfully updated device."
@ -3108,11 +3119,11 @@ msgstr "Successfully updated device."
msgid "Successfully updated flow."
msgstr "Successfully updated flow."
#: src/pages/groups/GroupForm.ts:41
#: src/pages/groups/GroupForm.ts:43
msgid "Successfully updated group."
msgstr "Successfully updated group."
#: src/pages/stages/invitation/InvitationForm.ts:35
#: src/pages/stages/invitation/InvitationForm.ts:36
msgid "Successfully updated invitation."
msgstr "Successfully updated invitation."
@ -3156,7 +3167,7 @@ msgid "Successfully updated service-connection."
msgstr "Successfully updated service-connection."
#: src/pages/sources/ldap/LDAPSourceForm.ts:44
#: src/pages/sources/oauth/OAuthSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:48
#: src/pages/sources/saml/SAMLSourceForm.ts:44
msgid "Successfully updated source."
msgstr "Successfully updated source."
@ -3339,7 +3350,7 @@ msgstr "Time in minutes the token sent is valid."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:62
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:77
msgid "Time-based One-Time Passwords"
msgstr "Time-based One-Time Passwords"
@ -3371,7 +3382,7 @@ msgstr "Token count"
msgid "Token expiry"
msgstr "Token expiry"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:135
msgid "Token validity"
msgstr "Token validity"
@ -3418,7 +3429,7 @@ msgstr "UI settings"
msgid "UID"
msgstr "UID"
#: src/pages/sources/oauth/OAuthSourceForm.ts:61
#: src/pages/sources/oauth/OAuthSourceForm.ts:62
msgid "URL settings"
msgstr "URL settings"
@ -3426,19 +3437,19 @@ msgstr "URL settings"
msgid "URL that the initial Login request is sent to."
msgstr "URL that the initial Login request is sent to."
#: src/pages/sources/oauth/OAuthSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:70
msgid "URL the user is redirect to to consent the authorization."
msgstr "URL the user is redirect to to consent the authorization."
#: src/pages/sources/oauth/OAuthSourceForm.ts:83
#: src/pages/sources/oauth/OAuthSourceForm.ts:84
msgid "URL used by authentik to get user information."
msgstr "URL used by authentik to get user information."
#: src/pages/sources/oauth/OAuthSourceForm.ts:76
#: src/pages/sources/oauth/OAuthSourceForm.ts:77
msgid "URL used by authentik to retrieve tokens."
msgstr "URL used by authentik to retrieve tokens."
#: src/pages/sources/oauth/OAuthSourceForm.ts:89
#: src/pages/sources/oauth/OAuthSourceForm.ts:90
msgid "URL used to request the initial token. This URL is only required for OAuth 1."
msgstr "URL used to request the initial token. This URL is only required for OAuth 1."
@ -3458,7 +3469,7 @@ msgstr "Unknown"
msgid "Up-to-date!"
msgstr "Up-to-date!"
#: src/pages/applications/ApplicationListPage.ts:86
#: src/pages/applications/ApplicationListPage.ts:87
#: src/pages/applications/ApplicationViewPage.ts:97
#: src/pages/crypto/CertificateKeyPairListPage.ts:66
#: src/pages/events/RuleListPage.ts:62
@ -3486,9 +3497,9 @@ msgstr "Up-to-date!"
#: src/pages/stages/StageListPage.ts:85
#: src/pages/stages/prompt/PromptListPage.ts:67
#: src/pages/user-settings/UserDetailsPage.ts:81
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:43
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:46
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:67
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:47
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:50
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:71
#: src/pages/user-settings/tokens/UserTokenList.ts:105
#: src/pages/users/UserActiveForm.ts:66
#: src/pages/users/UserListPage.ts:68
@ -3496,7 +3507,7 @@ msgstr "Up-to-date!"
msgid "Update"
msgstr "Update"
#: src/pages/applications/ApplicationListPage.ts:89
#: src/pages/applications/ApplicationListPage.ts:90
#: src/pages/applications/ApplicationViewPage.ts:100
msgid "Update Application"
msgstr "Update Application"
@ -3699,7 +3710,7 @@ msgstr "Username: Same as Text input, but checks for and prevents duplicate user
msgid "Users"
msgstr "Users"
#: src/pages/groups/GroupForm.ts:63
#: src/pages/groups/GroupForm.ts:65
msgid "Users added to this group will be superusers."
msgstr "Users added to this group will be superusers."
@ -3711,6 +3722,10 @@ msgstr "Using flow"
msgid "Using source"
msgstr "Using source"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:123
msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows."
msgstr "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows."
#: src/pages/providers/proxy/ProxyProviderForm.ts:115
msgid "Validate SSL Certificates of upstream servers."
msgstr "Validate SSL Certificates of upstream servers."
@ -3784,7 +3799,7 @@ msgstr "Warning: Provider not assigned to any application."
msgid "WebAuthn Authenticators"
msgstr "WebAuthn Authenticators"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:74
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:78
msgid "WebAuthn Devices"
msgstr "WebAuthn Devices"
@ -3852,7 +3867,7 @@ msgstr "X509 Subject"
#: src/pages/crypto/CertificateKeyPairListPage.ts:61
#: src/pages/groups/GroupListPage.ts:58
#: src/pages/groups/MemberSelectModal.ts:56
#: src/pages/groups/MemberSelectModal.ts:57
#: src/pages/outposts/ServiceConnectionListPage.ts:64
#: src/pages/policies/BoundPoliciesList.ts:118
#: src/pages/policies/PolicyTestForm.ts:38

View File

@ -68,7 +68,7 @@ msgstr ""
msgid "Access Key"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:72
#: src/pages/sources/oauth/OAuthSourceForm.ts:73
msgid "Access token URL"
msgstr ""
@ -79,13 +79,13 @@ msgstr ""
msgid "Action"
msgstr ""
#: src/pages/groups/MemberSelectModal.ts:45
#: src/pages/groups/MemberSelectModal.ts:46
#: src/pages/users/UserListPage.ts:51
#: src/pages/users/UserViewPage.ts:116
msgid "Active"
msgstr ""
#: src/pages/groups/MemberSelectModal.ts:82
#: src/pages/groups/MemberSelectModal.ts:83
msgid "Add"
msgstr ""
@ -105,7 +105,7 @@ msgstr ""
msgid "Additional user DN, prepended to the Base DN."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:128
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:131
#: src/pages/providers/proxy/ProxyProviderForm.ts:128
#: src/pages/providers/saml/SAMLProviderForm.ts:117
#: src/pages/sources/saml/SAMLSourceForm.ts:134
@ -125,7 +125,7 @@ msgstr ""
msgid "Alert"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152
msgid "Algorithm used to sign the JWT Tokens."
msgstr ""
@ -168,12 +168,12 @@ msgstr ""
#: src/elements/user/UserConsentList.ts:29
#: src/pages/admin-overview/TopApplicationsTable.ts:42
#: src/pages/applications/ApplicationListPage.ts:104
#: src/pages/applications/ApplicationListPage.ts:105
#: src/pages/providers/ProviderListPage.ts:53
msgid "Application"
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:68
#: src/pages/applications/ApplicationListPage.ts:69
msgid "Application Icon"
msgstr ""
@ -216,19 +216,19 @@ msgstr ""
msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:202
#: src/pages/providers/saml/SAMLProviderForm.ts:208
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:191
#: src/pages/providers/saml/SAMLProviderForm.ts:197
msgid "Assertion valid not before"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:195
#: src/pages/providers/saml/SAMLProviderForm.ts:201
msgid "Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3)."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:198
#: src/pages/providers/saml/SAMLProviderForm.ts:204
msgid "Assertion valid not on or after"
msgstr ""
@ -255,8 +255,8 @@ msgstr ""
msgid "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded."
msgstr ""
#: src/pages/groups/GroupForm.ts:134
#: src/pages/stages/invitation/InvitationForm.ts:51
#: src/pages/groups/GroupForm.ts:135
#: src/pages/stages/invitation/InvitationForm.ts:52
#: src/pages/users/UserForm.ts:77
msgid "Attributes"
msgstr ""
@ -270,13 +270,13 @@ msgstr ""
msgid "Authentication"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:165
#: src/pages/sources/oauth/OAuthSourceForm.ts:189
#: src/pages/sources/saml/SAMLSourceForm.ts:245
msgid "Authentication flow"
msgstr ""
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts:63
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:29
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:33
msgid "Authenticator"
msgstr ""
@ -288,7 +288,7 @@ msgstr ""
msgid "Authorization Code"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:65
#: src/pages/sources/oauth/OAuthSourceForm.ts:66
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:95
msgid "Authorization URL"
msgstr ""
@ -338,19 +338,19 @@ msgstr ""
msgid "Base DN"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:195
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204
msgid "Based on the Hashed User ID"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:201
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:210
msgid "Based on the User's Email. This is recommended over the UPN method."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213
msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:198
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207
msgid "Based on the username"
msgstr ""
@ -412,7 +412,7 @@ msgstr ""
#: src/elements/forms/ConfirmationForm.ts:75
#: src/elements/forms/DeleteForm.ts:86
#: src/elements/forms/ModalForm.ts:71
#: src/pages/groups/MemberSelectModal.ts:89
#: src/pages/groups/MemberSelectModal.ts:90
#: src/pages/users/UserActiveForm.ts:73
msgid "Cancel"
msgstr ""
@ -582,15 +582,15 @@ msgstr ""
msgid "Configuration flow"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:103
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:106
msgid "Configure WebAuthn"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:187
#: src/pages/providers/saml/SAMLProviderForm.ts:193
msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:233
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:242
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr ""
@ -598,15 +598,15 @@ msgstr ""
msgid "Configure settings relevant to your user profile."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:208
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr ""
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:47
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:43
msgid "Connect"
msgstr ""
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:34
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:30
msgid "Connected."
msgstr ""
@ -643,11 +643,11 @@ msgstr ""
msgid "Consider Objects matching this filter to be Users."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:124
#: src/pages/sources/oauth/OAuthSourceForm.ts:126
msgid "Consumer key"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:130
#: src/pages/sources/oauth/OAuthSourceForm.ts:132
msgid "Consumer secret"
msgstr ""
@ -689,8 +689,8 @@ msgid "Copy Key"
msgstr ""
#: src/pages/applications/ApplicationForm.ts:120
#: src/pages/applications/ApplicationListPage.ts:120
#: src/pages/applications/ApplicationListPage.ts:128
#: src/pages/applications/ApplicationListPage.ts:121
#: src/pages/applications/ApplicationListPage.ts:129
#: src/pages/crypto/CertificateKeyPairListPage.ts:122
#: src/pages/crypto/CertificateKeyPairListPage.ts:130
#: src/pages/events/RuleListPage.ts:91
@ -731,12 +731,12 @@ msgstr ""
#: src/pages/stages/prompt/PromptStageForm.ts:98
#: src/pages/user-settings/tokens/UserTokenList.ts:50
#: src/pages/user-settings/tokens/UserTokenList.ts:58
#: src/pages/users/UserListPage.ts:144
#: src/pages/users/UserListPage.ts:152
#: src/pages/users/UserListPage.ts:151
#: src/pages/users/UserListPage.ts:159
msgid "Create"
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:123
#: src/pages/applications/ApplicationListPage.ts:124
#: src/pages/providers/RelatedApplicationButton.ts:30
msgid "Create Application"
msgstr ""
@ -802,7 +802,7 @@ msgstr ""
msgid "Create Token"
msgstr ""
#: src/pages/users/UserListPage.ts:147
#: src/pages/users/UserListPage.ts:154
msgid "Create User"
msgstr ""
@ -826,7 +826,7 @@ msgstr ""
msgid "Created by"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:86
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:90
msgid "Created {0}"
msgstr ""
@ -840,7 +840,7 @@ msgstr ""
msgid "Customisation"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:249
#: src/pages/providers/saml/SAMLProviderForm.ts:255
#: src/pages/sources/saml/SAMLSourceForm.ts:212
msgid "DSA-SHA1"
msgstr ""
@ -862,7 +862,7 @@ msgid "Define how notifications are sent to users, like Email or Webhook."
msgstr ""
#: src/elements/forms/DeleteForm.ts:79
#: src/pages/applications/ApplicationListPage.ts:111
#: src/pages/applications/ApplicationListPage.ts:112
#: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86
@ -878,7 +878,7 @@ msgstr ""
#: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87
#: src/pages/tokens/TokenListPage.ts:68
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:36
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:40
#: src/pages/user-settings/tokens/UserTokenList.ts:125
#: src/pages/users/UserListPage.ts:115
msgid "Delete"
@ -955,11 +955,11 @@ msgstr ""
msgid "Device classes which can be used to authenticate."
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:59
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:63
msgid "Device name"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:213
#: src/pages/providers/saml/SAMLProviderForm.ts:219
#: src/pages/sources/saml/SAMLSourceForm.ts:176
msgid "Digest algorithm"
msgstr ""
@ -973,11 +973,11 @@ msgstr ""
msgid "Disable"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:51
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:55
msgid "Disable Static Tokens"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:36
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:40
msgid "Disable Time-based OTP"
msgstr ""
@ -985,7 +985,7 @@ msgstr ""
msgid "Disabled"
msgstr ""
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:41
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:37
msgid "Disconnect"
msgstr ""
@ -1002,11 +1002,11 @@ msgstr ""
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:235
msgid "Each provider has a different issuer, based on the application slug."
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:94
#: src/pages/applications/ApplicationListPage.ts:95
#: src/pages/applications/ApplicationViewPage.ts:91
#: src/pages/applications/ApplicationViewPage.ts:105
#: src/pages/crypto/CertificateKeyPairListPage.ts:74
@ -1088,18 +1088,18 @@ msgstr ""
msgid "Enable StartTLS"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:67
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:55
msgid "Enable Static Tokens"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:52
msgid "Enable Time-based OTP"
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:70
msgid "Enable TOTP"
msgstr ""
#: src/pages/policies/BoundPoliciesList.ts:37
#: src/pages/policies/PolicyBindingForm.ts:198
#: src/pages/sources/ldap/LDAPSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:113
#: src/pages/sources/oauth/OAuthSourceForm.ts:115
#: src/pages/sources/saml/SAMLSourceForm.ts:69
msgid "Enabled"
msgstr ""
@ -1108,7 +1108,7 @@ msgstr ""
msgid "Enrollment"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:186
#: src/pages/sources/oauth/OAuthSourceForm.ts:210
#: src/pages/sources/saml/SAMLSourceForm.ts:266
#: src/pages/stages/identification/IdentificationStageForm.ts:107
msgid "Enrollment flow"
@ -1201,7 +1201,7 @@ msgstr ""
#: src/elements/oauth/UserCodeList.ts:30
#: src/elements/oauth/UserRefreshList.ts:30
#: src/elements/user/UserConsentList.ts:30
#: src/pages/stages/invitation/InvitationForm.ts:45
#: src/pages/stages/invitation/InvitationForm.ts:46
msgid "Expires"
msgstr ""
@ -1247,7 +1247,7 @@ msgid "Expression using Python."
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:31
msgid "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML."
msgid "External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:90
@ -1320,17 +1320,17 @@ msgstr ""
msgid "Flow Overview"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:161
#: src/pages/sources/oauth/OAuthSourceForm.ts:185
#: src/pages/sources/saml/SAMLSourceForm.ts:220
msgid "Flow settings"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:183
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/saml/SAMLSourceForm.ts:263
msgid "Flow to use when authenticating existing users."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:204
#: src/pages/sources/oauth/OAuthSourceForm.ts:228
#: src/pages/sources/saml/SAMLSourceForm.ts:284
msgid "Flow to use when enrolling new users."
msgstr ""
@ -1443,7 +1443,7 @@ msgstr ""
msgid "Groups"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149
msgid "HS256 (Symmetric Encryption)"
msgstr ""
@ -1468,10 +1468,10 @@ msgid "Hide managed mappings"
msgstr ""
#: src/pages/events/RuleForm.ts:93
#: src/pages/groups/GroupForm.ts:131
#: src/pages/groups/GroupForm.ts:132
#: src/pages/outposts/OutpostForm.ts:98
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:169
#: src/pages/providers/saml/SAMLProviderForm.ts:171
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:178
#: src/pages/providers/saml/SAMLProviderForm.ts:177
#: src/pages/sources/ldap/LDAPSourceForm.ts:167
#: src/pages/sources/ldap/LDAPSourceForm.ts:193
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
@ -1523,7 +1523,7 @@ msgstr ""
msgid "If your authentik Instance is using a self-signed certificate, set this value."
msgstr ""
#: src/pages/users/UserListPage.ts:136
#: src/pages/users/UserListPage.ts:143
msgid "Impersonate"
msgstr ""
@ -1544,11 +1544,11 @@ msgstr ""
msgid "In case you can't access any other method."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:218
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:227
msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:215
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:224
msgid "Include claims in id_token"
msgstr ""
@ -1581,7 +1581,7 @@ msgstr ""
msgid "Is active"
msgstr ""
#: src/pages/groups/GroupForm.ts:60
#: src/pages/groups/GroupForm.ts:62
msgid "Is superuser"
msgstr ""
@ -1592,15 +1592,15 @@ msgstr ""
msgid "Issuer"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:221
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230
msgid "Issuer mode"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:138
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:141
msgid "JWT Algorithm"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:187
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:196
msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
msgstr ""
@ -1625,7 +1625,7 @@ msgstr ""
msgid "Label shown next to/above the prompt."
msgstr ""
#: src/pages/groups/MemberSelectModal.ts:46
#: src/pages/groups/MemberSelectModal.ts:47
#: src/pages/users/UserListPage.ts:52
#: src/pages/users/UserViewPage.ts:108
msgid "Last login"
@ -1672,6 +1672,7 @@ msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:134
#: src/flows/stages/password/PasswordStage.ts:31
#: src/flows/stages/prompt/PromptStage.ts:126
#: src/pages/applications/ApplicationViewPage.ts:43
#: src/pages/applications/ApplicationViewPage.ts:54
#: src/pages/user-settings/UserDetailsPage.ts:38
#: src/utils.ts:40
@ -1684,8 +1685,8 @@ msgstr ""
#: src/pages/events/RuleForm.ts:90
#: src/pages/flows/StageBindingForm.ts:89
#: src/pages/flows/StageBindingForm.ts:106
#: src/pages/groups/GroupForm.ts:76
#: src/pages/groups/GroupForm.ts:127
#: src/pages/groups/GroupForm.ts:77
#: src/pages/groups/GroupForm.ts:128
#: src/pages/outposts/OutpostForm.ts:74
#: src/pages/outposts/OutpostForm.ts:96
#: src/pages/outposts/ServiceConnectionDockerForm.ts:87
@ -1698,21 +1699,21 @@ msgstr ""
#: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:108
#: src/pages/property-mappings/PropertyMappingTestForm.ts:59
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:166
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:175
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:194
#: src/pages/providers/proxy/ProxyProviderForm.ts:92
#: src/pages/providers/proxy/ProxyProviderForm.ts:143
#: src/pages/providers/saml/SAMLProviderForm.ts:71
#: src/pages/providers/saml/SAMLProviderForm.ts:133
#: src/pages/providers/saml/SAMLProviderForm.ts:149
#: src/pages/providers/saml/SAMLProviderForm.ts:169
#: src/pages/providers/saml/SAMLProviderForm.ts:185
#: src/pages/providers/saml/SAMLProviderForm.ts:175
#: src/pages/providers/saml/SAMLProviderForm.ts:191
#: src/pages/providers/saml/SAMLProviderImportForm.ts:55
#: src/pages/sources/ldap/LDAPSourceForm.ts:164
#: src/pages/sources/ldap/LDAPSourceForm.ts:190
#: src/pages/sources/oauth/OAuthSourceForm.ts:153
#: src/pages/sources/oauth/OAuthSourceForm.ts:181
#: src/pages/sources/oauth/OAuthSourceForm.ts:202
#: src/pages/sources/oauth/OAuthSourceForm.ts:177
#: src/pages/sources/oauth/OAuthSourceForm.ts:205
#: src/pages/sources/oauth/OAuthSourceForm.ts:226
#: src/pages/sources/saml/SAMLSourceForm.ts:126
#: src/pages/sources/saml/SAMLSourceForm.ts:240
#: src/pages/sources/saml/SAMLSourceForm.ts:261
@ -1788,7 +1789,7 @@ msgstr ""
msgid "Maximum age (in days)"
msgstr ""
#: src/pages/groups/GroupForm.ts:80
#: src/pages/groups/GroupForm.ts:81
#: src/pages/groups/GroupListPage.ts:47
msgid "Members"
msgstr ""
@ -1837,7 +1838,7 @@ msgid "Monitor"
msgstr ""
#: src/pages/applications/ApplicationForm.ts:86
#: src/pages/applications/ApplicationListPage.ts:57
#: src/pages/applications/ApplicationListPage.ts:58
#: src/pages/crypto/CertificateKeyPairForm.ts:45
#: src/pages/crypto/CertificateKeyPairListPage.ts:51
#: src/pages/events/EventInfo.ts:51
@ -1848,9 +1849,9 @@ msgstr ""
#: src/pages/flows/BoundStagesList.ts:39
#: src/pages/flows/FlowForm.ts:81
#: src/pages/flows/FlowListPage.ts:47
#: src/pages/groups/GroupForm.ts:51
#: src/pages/groups/GroupForm.ts:53
#: src/pages/groups/GroupListPage.ts:45
#: src/pages/groups/MemberSelectModal.ts:44
#: src/pages/groups/MemberSelectModal.ts:45
#: src/pages/outposts/OutpostForm.ts:47
#: src/pages/outposts/OutpostListPage.ts:50
#: src/pages/outposts/ServiceConnectionDockerForm.ts:53
@ -1879,7 +1880,7 @@ msgstr ""
#: src/pages/sources/SourcesListPage.ts:51
#: src/pages/sources/ldap/LDAPSourceForm.ts:54
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:98
#: src/pages/sources/oauth/OAuthSourceForm.ts:100
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:54
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66
@ -1916,7 +1917,7 @@ msgstr ""
msgid "NameID Policy"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:174
#: src/pages/providers/saml/SAMLProviderForm.ts:180
msgid "NameID Property Mapping"
msgstr ""
@ -1931,7 +1932,7 @@ msgstr ""
#: src/pages/crypto/CertificateKeyPairListPage.ts:61
#: src/pages/groups/GroupListPage.ts:58
#: src/pages/groups/MemberSelectModal.ts:56
#: src/pages/groups/MemberSelectModal.ts:57
#: src/pages/outposts/ServiceConnectionListPage.ts:64
#: src/pages/policies/BoundPoliciesList.ts:118
#: src/pages/policies/PolicyTestForm.ts:38
@ -1988,6 +1989,10 @@ msgstr ""
msgid "No policies cached. Users may experience slow response times."
msgstr ""
#: src/pages/users/UserListPage.ts:135
msgid "No recovery flow is configured."
msgstr ""
#: src/pages/flows/BoundStagesList.ts:114
msgid "No stages are currently bound to this flow."
msgstr ""
@ -2008,7 +2013,7 @@ msgstr ""
msgid "Not configured action"
msgstr ""
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:44
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:40
msgid "Not connected."
msgstr ""
@ -2102,7 +2107,7 @@ msgstr ""
msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:99
#: src/pages/applications/ApplicationListPage.ts:100
msgid "Open application"
msgstr ""
@ -2122,7 +2127,7 @@ msgstr ""
msgid "Optional URL if the IDP supports Single-Logout."
msgstr ""
#: src/pages/stages/invitation/InvitationForm.ts:55
#: src/pages/stages/invitation/InvitationForm.ts:56
msgid "Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON."
msgstr ""
@ -2196,7 +2201,7 @@ msgstr ""
msgid "PEM-encoded Certificate data."
msgstr ""
#: src/pages/groups/GroupForm.ts:66
#: src/pages/groups/GroupForm.ts:68
#: src/pages/groups/GroupListPage.ts:46
msgid "Parent"
msgstr ""
@ -2326,7 +2331,7 @@ msgstr ""
msgid "Private key, acquired from https://www.google.com/recaptcha/intro/v3.html."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:79
#: src/pages/sources/oauth/OAuthSourceForm.ts:80
msgid "Profile URL"
msgstr ""
@ -2368,7 +2373,7 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81
#: src/pages/providers/proxy/ProxyProviderForm.ts:99
#: src/pages/providers/saml/SAMLProviderForm.ts:78
#: src/pages/sources/oauth/OAuthSourceForm.ts:120
#: src/pages/sources/oauth/OAuthSourceForm.ts:122
#: src/pages/sources/saml/SAMLSourceForm.ts:76
msgid "Protocol settings"
msgstr ""
@ -2380,18 +2385,17 @@ msgstr ""
#: src/elements/oauth/UserCodeList.ts:29
#: src/elements/oauth/UserRefreshList.ts:29
#: src/pages/applications/ApplicationForm.ts:100
#: src/pages/applications/ApplicationListPage.ts:59
#: src/pages/applications/ApplicationListPage.ts:60
#: src/pages/applications/ApplicationViewPage.ts:68
#: src/pages/providers/ProviderListPage.ts:34
msgid "Provider"
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:60
#: src/pages/applications/ApplicationListPage.ts:61
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:71
msgid "Provider Type"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:136
#: src/pages/sources/oauth/OAuthSourceForm.ts:138
msgid "Provider type"
msgstr ""
@ -2399,6 +2403,7 @@ msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts:46
#: src/pages/outposts/OutpostForm.ts:82
#: src/pages/outposts/OutpostListPage.ts:51
#: src/pages/providers/ProviderListPage.ts:34
msgid "Providers"
msgstr ""
@ -2422,30 +2427,30 @@ msgstr ""
msgid "Publisher"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:143
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146
msgid "RS256 (Asymmetric Encryption)"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:172
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:181
msgid "RSA Key"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:237
#: src/pages/providers/saml/SAMLProviderForm.ts:243
#: src/pages/sources/saml/SAMLSourceForm.ts:200
msgid "RSA-SHA1"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:240
#: src/pages/providers/saml/SAMLProviderForm.ts:246
#: src/pages/sources/saml/SAMLSourceForm.ts:203
msgid "RSA-SHA256"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:243
#: src/pages/providers/saml/SAMLProviderForm.ts:249
#: src/pages/sources/saml/SAMLSourceForm.ts:206
msgid "RSA-SHA384"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:246
#: src/pages/providers/saml/SAMLProviderForm.ts:252
#: src/pages/sources/saml/SAMLSourceForm.ts:209
msgid "RSA-SHA512"
msgstr ""
@ -2470,11 +2475,14 @@ msgstr ""
msgid "Redirect"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:119
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:107
msgid "Redirect URIs"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:119
msgid "Redirect URIs/Origins"
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts:104
msgid "Redirect binding"
msgstr ""
@ -2517,7 +2525,7 @@ msgstr ""
msgid "Request has been denied."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:86
#: src/pages/sources/oauth/OAuthSourceForm.ts:87
msgid "Request token URL"
msgstr ""
@ -2530,7 +2538,7 @@ msgstr ""
msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr ""
#: src/pages/users/UserListPage.ts:133
#: src/pages/users/UserListPage.ts:140
#: src/pages/users/UserViewPage.ts:165
msgid "Reset Password"
msgstr ""
@ -2570,22 +2578,22 @@ msgstr ""
msgid "SAML Attribute Name"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:218
#: src/pages/providers/saml/SAMLProviderForm.ts:224
#: src/pages/sources/saml/SAMLSourceForm.ts:181
msgid "SHA1"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:221
#: src/pages/providers/saml/SAMLProviderForm.ts:227
#: src/pages/sources/saml/SAMLSourceForm.ts:184
msgid "SHA256"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:224
#: src/pages/providers/saml/SAMLProviderForm.ts:230
#: src/pages/sources/saml/SAMLSourceForm.ts:187
msgid "SHA384"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:227
#: src/pages/providers/saml/SAMLProviderForm.ts:233
#: src/pages/sources/saml/SAMLSourceForm.ts:190
msgid "SHA512"
msgstr ""
@ -2616,7 +2624,7 @@ msgstr ""
msgid "SSO URL"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:229
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:238
msgid "Same identifier is used for all providers"
msgstr ""
@ -2630,7 +2638,7 @@ msgstr ""
#: src/elements/oauth/UserCodeList.ts:31
#: src/elements/oauth/UserRefreshList.ts:31
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:155
msgid "Scopes"
msgstr ""
@ -2661,11 +2669,11 @@ msgstr ""
msgid "Select an identification method."
msgstr ""
#: src/pages/groups/MemberSelectModal.ts:67
#: src/pages/groups/MemberSelectModal.ts:68
msgid "Select users to add"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:168
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:177
msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
msgstr ""
@ -2726,11 +2734,11 @@ msgstr ""
msgid "Session duration"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:209
#: src/pages/providers/saml/SAMLProviderForm.ts:215
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:205
#: src/pages/providers/saml/SAMLProviderForm.ts:211
msgid "Session valid not on or after"
msgstr ""
@ -2742,7 +2750,7 @@ msgstr ""
msgid "Set a custom HTTP-Basic Authentication header based on values from authentik."
msgstr ""
#: src/pages/groups/GroupForm.ts:138
#: src/pages/groups/GroupForm.ts:139
#: src/pages/outposts/OutpostForm.ts:109
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts:73
#: src/pages/policies/PolicyTestForm.ts:78
@ -2771,7 +2779,7 @@ msgstr ""
msgid "Sign up."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:232
#: src/pages/providers/saml/SAMLProviderForm.ts:238
#: src/pages/sources/saml/SAMLSourceForm.ts:195
msgid "Signature algorithm"
msgstr ""
@ -2793,10 +2801,10 @@ msgid "Skip path regex"
msgstr ""
#: src/pages/applications/ApplicationForm.ts:93
#: src/pages/applications/ApplicationListPage.ts:58
#: src/pages/applications/ApplicationListPage.ts:59
#: src/pages/flows/FlowForm.ts:94
#: src/pages/sources/ldap/LDAPSourceForm.ts:60
#: src/pages/sources/oauth/OAuthSourceForm.ts:104
#: src/pages/sources/oauth/OAuthSourceForm.ts:106
#: src/pages/sources/saml/SAMLSourceForm.ts:60
msgid "Slug"
msgstr ""
@ -2810,7 +2818,7 @@ msgstr ""
msgid "Source"
msgstr ""
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:21
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts:18
msgid "Source {0}"
msgstr ""
@ -2889,10 +2897,13 @@ msgid "State"
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:104
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:77
msgid "Static Tokens"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:62
msgid "Static tokens"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts:75
msgid "Static: Static value, displayed as-is."
msgstr ""
@ -2905,13 +2916,13 @@ msgstr ""
msgid "Status"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:44
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:59
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:48
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:63
msgid "Status: Disabled"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:18
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:22
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:22
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:26
msgid "Status: Enabled"
msgstr ""
@ -2923,7 +2934,7 @@ msgstr ""
msgid "Subject"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:190
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:199
msgid "Subject mode"
msgstr ""
@ -2964,11 +2975,11 @@ msgstr ""
msgid "Successfully created flow."
msgstr ""
#: src/pages/groups/GroupForm.ts:44
#: src/pages/groups/GroupForm.ts:46
msgid "Successfully created group."
msgstr ""
#: src/pages/stages/invitation/InvitationForm.ts:38
#: src/pages/stages/invitation/InvitationForm.ts:39
msgid "Successfully created invitation."
msgstr ""
@ -3012,7 +3023,7 @@ msgid "Successfully created service-connection."
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:50
#: src/pages/sources/oauth/OAuthSourceForm.ts:51
#: src/pages/sources/saml/SAMLSourceForm.ts:47
msgid "Successfully created source."
msgstr ""
@ -3092,7 +3103,7 @@ msgstr ""
msgid "Successfully updated details."
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:50
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:54
msgid "Successfully updated device."
msgstr ""
@ -3100,11 +3111,11 @@ msgstr ""
msgid "Successfully updated flow."
msgstr ""
#: src/pages/groups/GroupForm.ts:41
#: src/pages/groups/GroupForm.ts:43
msgid "Successfully updated group."
msgstr ""
#: src/pages/stages/invitation/InvitationForm.ts:35
#: src/pages/stages/invitation/InvitationForm.ts:36
msgid "Successfully updated invitation."
msgstr ""
@ -3148,7 +3159,7 @@ msgid "Successfully updated service-connection."
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:44
#: src/pages/sources/oauth/OAuthSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:48
#: src/pages/sources/saml/SAMLSourceForm.ts:44
msgid "Successfully updated source."
msgstr ""
@ -3329,7 +3340,7 @@ msgstr ""
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts:62
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts:77
msgid "Time-based One-Time Passwords"
msgstr ""
@ -3361,7 +3372,7 @@ msgstr ""
msgid "Token expiry"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:135
msgid "Token validity"
msgstr ""
@ -3408,7 +3419,7 @@ msgstr ""
msgid "UID"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:61
#: src/pages/sources/oauth/OAuthSourceForm.ts:62
msgid "URL settings"
msgstr ""
@ -3416,19 +3427,19 @@ msgstr ""
msgid "URL that the initial Login request is sent to."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:70
msgid "URL the user is redirect to to consent the authorization."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:83
#: src/pages/sources/oauth/OAuthSourceForm.ts:84
msgid "URL used by authentik to get user information."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:76
#: src/pages/sources/oauth/OAuthSourceForm.ts:77
msgid "URL used by authentik to retrieve tokens."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:89
#: src/pages/sources/oauth/OAuthSourceForm.ts:90
msgid "URL used to request the initial token. This URL is only required for OAuth 1."
msgstr ""
@ -3448,7 +3459,7 @@ msgstr ""
msgid "Up-to-date!"
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:86
#: src/pages/applications/ApplicationListPage.ts:87
#: src/pages/applications/ApplicationViewPage.ts:97
#: src/pages/crypto/CertificateKeyPairListPage.ts:66
#: src/pages/events/RuleListPage.ts:62
@ -3476,9 +3487,9 @@ msgstr ""
#: src/pages/stages/StageListPage.ts:85
#: src/pages/stages/prompt/PromptListPage.ts:67
#: src/pages/user-settings/UserDetailsPage.ts:81
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:43
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:46
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:67
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:47
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:50
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:71
#: src/pages/user-settings/tokens/UserTokenList.ts:105
#: src/pages/users/UserActiveForm.ts:66
#: src/pages/users/UserListPage.ts:68
@ -3486,7 +3497,7 @@ msgstr ""
msgid "Update"
msgstr ""
#: src/pages/applications/ApplicationListPage.ts:89
#: src/pages/applications/ApplicationListPage.ts:90
#: src/pages/applications/ApplicationViewPage.ts:100
msgid "Update Application"
msgstr ""
@ -3689,7 +3700,7 @@ msgstr ""
msgid "Users"
msgstr ""
#: src/pages/groups/GroupForm.ts:63
#: src/pages/groups/GroupForm.ts:65
msgid "Users added to this group will be superusers."
msgstr ""
@ -3701,6 +3712,10 @@ msgstr ""
msgid "Using source"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:123
msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts:115
msgid "Validate SSL Certificates of upstream servers."
msgstr ""
@ -3774,7 +3789,7 @@ msgstr ""
msgid "WebAuthn Authenticators"
msgstr ""
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:74
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts:78
msgid "WebAuthn Devices"
msgstr ""
@ -3840,7 +3855,7 @@ msgstr ""
#: src/pages/crypto/CertificateKeyPairListPage.ts:61
#: src/pages/groups/GroupListPage.ts:58
#: src/pages/groups/MemberSelectModal.ts:56
#: src/pages/groups/MemberSelectModal.ts:57
#: src/pages/outposts/ServiceConnectionListPage.ts:64
#: src/pages/policies/BoundPoliciesList.ts:118
#: src/pages/policies/PolicyTestForm.ts:38

View File

@ -22,7 +22,7 @@ export class ApplicationListPage extends TablePage<Application> {
return t`Applications`;
}
pageDescription(): string {
return t`External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML.`;
return t`External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`;
}
pageIcon(): string {
return "pf-icon pf-icon-applications";
@ -37,6 +37,7 @@ export class ApplicationListPage extends TablePage<Application> {
page: page,
pageSize: PAGE_SIZE,
search: this.search || "",
superuserFullList: true,
});
}

View File

@ -43,7 +43,7 @@ export class ApplicationViewPage extends LitElement {
render(): TemplateResult {
return html`<ak-page-header
icon=${this.application?.metaIcon || ""}
header=${this.application?.name}
header=${this.application?.name || t`Loading`}
description=${ifDefined(this.application?.metaPublisher)}
.iconImage=${true}>
</ak-page-header>

View File

@ -29,12 +29,13 @@ export class GroupForm extends Form<Group> {
}
send = (data: Group): Promise<Group> => {
if (this.group) {
if (this.group?.pk) {
return new CoreApi(DEFAULT_CONFIG).coreGroupsUpdate({
groupUuid: this.group.pk || "",
data: data
});
} else {
data.users = Array.from(this.group?.users || []) as unknown as Set<number>;
return new CoreApi(DEFAULT_CONFIG).coreGroupsCreate({
data: data
});
@ -60,7 +61,6 @@ export class GroupForm extends Form<Group> {
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Parent`}
?required=${true}
name="parent">
<select class="pf-c-form-control">
<option value="" ?selected=${this.group?.parent === undefined}>---------</option>
@ -80,7 +80,7 @@ export class GroupForm extends Form<Group> {
.confirm=${(items: User[]) => {
// Because the model only has the IDs, map the user list to IDs
const ids = items.map(u => u.pk || 0);
if (!this.group) return Promise.reject();
if (!this.group) this.group = {} as Group;
this.group.users = new Set(Array.from(this.group?.users || []).concat(ids));
this.requestUpdate();
return Promise.resolve();
@ -122,7 +122,7 @@ export class GroupForm extends Form<Group> {
<ak-form-element-horizontal
label=${t`Attributes`}
name="attributes">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.group?.attributes)}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.group?.attributes, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -21,6 +21,8 @@ export class MemberSelectTable extends TableModal<User> {
@property()
confirm!: (selectedItems: User[]) => Promise<unknown>;
order = "username";
apiEndpoint(page: number): Promise<AKResponse<User>> {
return new CoreApi(DEFAULT_CONFIG).coreUsersList({
ordering: this.order,
@ -40,10 +42,10 @@ export class MemberSelectTable extends TableModal<User> {
row(item: User): TemplateResult[] {
return [
html`<a href="#/identity/users/${item.pk}">
html`<div>
<div>${item.username}</div>
<small>${item.name}</small>
</a>`,
</div>`,
html`${item.isActive ? t`Yes` : t`No`}`,
html`${first(item.lastLogin?.toLocaleString(), "-")}`,
];

View File

@ -65,7 +65,7 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
<ak-form-element-horizontal
label=${t`Kubeconfig`}
name="kubeconfig">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.sc?.kubeconfig)}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.sc?.kubeconfig, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -9,6 +9,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import { PolicyTest } from "authentik-api/src";
import YAML from "yaml";
@customElement("ak-policy-test-form")
export class PolicyTestForm extends Form<PolicyTest> {
@ -75,7 +76,7 @@ export class PolicyTestForm extends Form<PolicyTest> {
<ak-form-element-horizontal
label=${t`Context`}
name="context">
<ak-codemirror mode="yaml">
<ak-codemirror mode="yaml" value=${YAML.stringify({})}>>
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -9,6 +9,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import { PolicyTest } from "authentik-api/src";
import YAML from "yaml";
@customElement("ak-property-mapping-test-form")
export class PolicyTestForm extends Form<PolicyTest> {
@ -26,7 +27,8 @@ export class PolicyTestForm extends Form<PolicyTest> {
send = (data: PolicyTest): Promise<PropertyMappingTestResult> => {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllTest({
pmUuid: this.mapping?.pk || "",
data: data
data: data,
formatResult: true,
}).then(result => this.result = result);
};
@ -64,7 +66,7 @@ export class PolicyTestForm extends Form<PolicyTest> {
<ak-form-element-horizontal
label=${t`Context`}
name="context">
<ak-codemirror mode="yaml">
<ak-codemirror mode="yaml" value=${YAML.stringify({})}>
</ak-codemirror>
</ak-form-element-horizontal>
${this.result ? this.renderResult(): html``}

View File

@ -25,7 +25,7 @@ export class ProviderListPage extends TablePage<Provider> {
return true;
}
pageTitle(): string {
return t`Provider`;
return t`Providers`;
}
pageDescription(): string {
return t`Provide support for protocols like SAML and OAuth to assigned applications.`;

View File

@ -113,9 +113,12 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
<input type="text" value="${first(this.provider?.clientSecret, randomString(128))}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Redirect URIs`}
label=${t`Redirect URIs/Origins`}
name="redirectUris">
<textarea class="pf-c-form-control">${this.provider?.redirectUris}</textarea>
<p class="pf-c-form__helper-text">
${t`Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows.`}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
@ -154,9 +157,14 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
ordering: "scope_name"
}).then(scopes => {
return scopes.results.map(scope => {
const selected = Array.from(this.provider?.propertyMappings || []).some(su => {
return su == scope.pk;
});
let selected = false;
if (!this.provider?.propertyMappings) {
selected = scope.managed?.startsWith("goauthentik.io/providers/oauth2/scope-") || false;
} else {
selected = Array.from(this.provider?.propertyMappings).some(su => {
return su == scope.pk;
});
}
return html`<option value=${ifDefined(scope.pk)} ?selected=${selected}>${scope.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}

View File

@ -154,9 +154,14 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
ordering: "saml_name"
}).then(mappings => {
return mappings.results.map(mapping => {
const selected = Array.from(this.provider?.propertyMappings || []).some(su => {
return su == mapping.pk;
});
let selected = false;
if (!this.provider?.propertyMappings) {
selected = mapping.managed?.startsWith("goauthentik.io/providers/saml") || false;
} else {
selected = Array.from(this.provider?.propertyMappings).some(su => {
return su == mapping.pk;
});
}
return html`<option value=${ifDefined(mapping.pk)} ?selected=${selected}>${mapping.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}

View File

@ -128,6 +128,9 @@ export class SourceListPage extends TablePage<Source> {
</span>
<ak-proxy-form
slot="form"
.args=${{
"modelName": type.modelName
}}
type=${type.component}>
</ak-proxy-form>
<button slot="trigger" class="pf-c-dropdown__menu-item">

View File

@ -22,12 +22,18 @@ export class OAuthSourceForm extends Form<OAuthSource> {
});
}
@property()
modelName?: string;
@property({attribute: false})
source?: OAuthSource;
@property({type: Boolean})
showUrlOptions = false;
@property({type: Boolean})
showRequestTokenURL = false;
getSuccessMessage(): string {
if (this.source) {
return t`Successfully updated source.`;
@ -63,29 +69,30 @@ export class OAuthSourceForm extends Form<OAuthSource> {
label=${t`Authorization URL`}
?required=${true}
name="authorizationUrl">
<input type="text" value="${ifDefined(this.source?.authorizationUrl)}" class="pf-c-form-control" required>
<input type="text" value="${first(this.source?.authorizationUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL the user is redirect to to consent the authorization.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Access token URL`}
?required=${true}
name="accessTokenUrl">
<input type="text" value="${ifDefined(this.source?.accessTokenUrl)}" class="pf-c-form-control" required>
<input type="text" value="${first(this.source?.accessTokenUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL used by authentik to retrieve tokens.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Profile URL`}
?required=${true}
name="profileUrl">
<input type="text" value="${ifDefined(this.source?.profileUrl)}" class="pf-c-form-control" required>
<input type="text" value="${first(this.source?.profileUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL used by authentik to get user information.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
${this.showRequestTokenURL ? html`<ak-form-element-horizontal
label=${t`Request token URL`}
name="requestTokenUrl">
<input type="text" value="${ifDefined(this.source?.requestTokenUrl)}" class="pf-c-form-control">
<input type="text" value="${first(this.source?.requestTokenUrl, "")}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`URL used to request the initial token. This URL is only required for OAuth 1.`}</p>
</ak-form-element-horizontal>
` : html``}
</div>
</ak-form-group>`;
}
@ -141,10 +148,31 @@ export class OAuthSourceForm extends Form<OAuthSource> {
} else {
this.showUrlOptions = false;
}
if ("data-request-token" in selected.attributes) {
this.showRequestTokenURL = true;
} else {
this.showRequestTokenURL = false;
}
if (!this.source) {
this.source = {} as OAuthSource;
}
this.source.providerType = selected.value;
}}>
${until(new SourcesApi(DEFAULT_CONFIG).sourcesOauthSourceTypes().then(types => {
return types.map(type => {
return html`<option ?data-urls-custom=${type.urlsCustomizable} value=${type.slug} ?selected=${this.source?.providerType === type.slug}>${type.name}</option>`;
let selected = this.source?.providerType === type.slug;
if (!this.source?.pk) {
if (this.modelName?.replace("oauthsource", "") === type.slug) {
selected = true;
}
}
return html`<option
?data-urls-custom=${type.urlsCustomizable}
?data-request-token=${type.requestTokenUrl}
value=${type.slug}
?selected=${selected}>
${type.name}
</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>

View File

@ -7,6 +7,7 @@ import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/CodeMirror";
import YAML from "yaml";
import { first } from "../../../utils";
@customElement("ak-invitation-form")
export class InvitationForm extends Form<Invitation> {
@ -46,7 +47,7 @@ export class InvitationForm extends Form<Invitation> {
<ak-form-element-horizontal
label=${t`Attributes`}
name="fixedData">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.invitation?.fixedData)}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.invitation?.fixedData, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -56,7 +56,7 @@ export class UserSettingsPage extends LitElement {
renderSourceSettings(source: UserSetting): TemplateResult {
switch (source.component) {
case "ak-user-settings-source-oauth":
return html`<ak-user-settings-source-oauth objectId=${source.objectUid}>
return html`<ak-user-settings-source-oauth objectId=${source.objectUid} title=${source.title}>
</ak-user-settings-source-oauth>`;
default:
return html`<p>${t`Error: unsupported source settings: ${source.component}`}</p>`;

View File

@ -1,6 +1,6 @@
import { customElement, html, TemplateResult } from "lit-element";
import { customElement, html, property, TemplateResult } from "lit-element";
import { BaseUserSettings } from "./BaseUserSettings";
import { OAuthSource, SourcesApi } from "authentik-api";
import { SourcesApi } from "authentik-api";
import { until } from "lit-html/directives/until";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { t } from "@lingui/macro";
@ -9,22 +9,21 @@ import { AppURLManager } from "../../../api/legacy";
@customElement("ak-user-settings-source-oauth")
export class SourceSettingsOAuth extends BaseUserSettings {
@property()
title!: string;
render(): TemplateResult {
return html`${until(new SourcesApi(DEFAULT_CONFIG).sourcesOauthRead({
slug: this.objectId
}).then((source) => {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">
${t`Source ${source.name}`}
</div>
<div class="pf-c-card__body">
${this.renderInner(source)}
</div>
</div>`;
}))}`;
return html`<div class="pf-c-card">
<div class="pf-c-card__title">
${t`Source ${this.title}`}
</div>
<div class="pf-c-card__body">
${this.renderInner()}
</div>
</div>`;
}
renderInner(source: OAuthSource): TemplateResult {
renderInner(): TemplateResult {
return html`${until(new SourcesApi(DEFAULT_CONFIG).sourcesOauthUserConnectionsList({
sourceSlug: this.objectId
}).then((connection) => {
@ -41,7 +40,7 @@ export class SourceSettingsOAuth extends BaseUserSettings {
}
return html`<p>${t`Not connected.`}</p>
<a class="pf-c-button pf-m-primary"
href=${AppURLManager.sourceOAuth(source.slug, "login")}>
href=${AppURLManager.sourceOAuth(this.objectId, "login")}>
${t`Connect`}
</a>`;
}))}`;

View File

@ -1,6 +1,6 @@
import { AuthenticatorsApi, StagesApi } from "authentik-api";
import { AuthenticatorsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, html, TemplateResult } from "lit-element";
import { customElement, html, property, TemplateResult } from "lit-element";
import { until } from "lit-html/directives/until";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { FlowURLManager } from "../../../api/legacy";
@ -9,6 +9,9 @@ import { BaseUserSettings } from "./BaseUserSettings";
@customElement("ak-user-settings-authenticator-static")
export class UserSettingsAuthenticatorStatic extends BaseUserSettings {
@property({ type: Boolean })
configureFlow = false;
renderEnabled(): TemplateResult {
return html`<div class="pf-c-card__body">
<p>
@ -44,21 +47,17 @@ export class UserSettingsAuthenticatorStatic extends BaseUserSettings {
</p>
</div>
<div class="pf-c-card__footer">
${until(new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorTotpRead({ stageUuid: this.objectId}).then((stage) => {
if (stage.configureFlow) {
return html`<a href="${FlowURLManager.configure(stage.pk || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Enable Time-based OTP`}
</a>`;
}
return html``;
}))}
${this.configureFlow ?
html`<a href="${FlowURLManager.configure(this.objectId || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Enable Static Tokens`}
</a>`: html``}
</div>`;
}
render(): TemplateResult {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">
${t`Time-based One-Time Passwords`}
${t`Static tokens`}
</div>
${until(new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsTotpList({}).then((devices) => {
return devices.results.length > 0 ? this.renderEnabled() : this.renderDisabled();

View File

@ -1,6 +1,6 @@
import { AuthenticatorsApi, StagesApi } from "authentik-api";
import { AuthenticatorsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, TemplateResult } from "lit-element";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { until } from "lit-html/directives/until";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { FlowURLManager } from "../../../api/legacy";
@ -10,6 +10,9 @@ import { BaseUserSettings } from "./BaseUserSettings";
@customElement("ak-user-settings-authenticator-totp")
export class UserSettingsAuthenticatorTOTP extends BaseUserSettings {
@property({ type: Boolean })
configureFlow = false;
static get styles(): CSSResult[] {
return super.styles.concat(STATIC_TOKEN_STYLE);
}
@ -59,21 +62,17 @@ export class UserSettingsAuthenticatorTOTP extends BaseUserSettings {
</p>
</div>
<div class="pf-c-card__footer">
${until(new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorStaticRead({ stageUuid: this.objectId}).then((stage) => {
if (stage.configureFlow) {
return html`<a href="${FlowURLManager.configure(stage.pk || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Enable Static Tokens`}
</a>`;
}
return html``;
}))}
${this.configureFlow ?
html`<a href="${FlowURLManager.configure(this.objectId || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Enable TOTP`}
</a>`: html``}
</div>`;
}
render(): TemplateResult {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">
${t`Static Tokens`}
${t`Time-based One-Time Passwords`}
</div>
${until(new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsTotpList({}).then((devices) => {
return devices.results.length > 0 ? this.renderEnabled() : this.renderDisabled();

View File

@ -1,6 +1,6 @@
import { CSSResult, customElement, html, TemplateResult } from "lit-element";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { t } from "@lingui/macro";
import { AuthenticatorsApi, StagesApi, WebAuthnDevice } from "authentik-api";
import { AuthenticatorsApi, WebAuthnDevice } from "authentik-api";
import { until } from "lit-html/directives/until";
import { FlowURLManager } from "../../../api/legacy";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -17,6 +17,9 @@ import { ifDefined } from "lit-html/directives/if-defined";
@customElement("ak-user-settings-authenticator-webauthn")
export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
@property({type: Boolean})
configureFlow = false;
static get styles(): CSSResult[] {
return super.styles.concat(PFDataList);
}
@ -96,14 +99,10 @@ export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
</ul>
</div>
<div class="pf-c-card__footer">
${until(new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnRead({ stageUuid: this.objectId}).then((stage) => {
if (stage.configureFlow) {
return html`<a href="${FlowURLManager.configure(stage.pk || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Configure WebAuthn`}
</a>`;
}
return html``;
}))}
${this.configureFlow ?
html`<a href="${FlowURLManager.configure(this.objectId || "", "?next=/%23%2Fuser")}"
class="pf-c-button pf-m-primary">${t`Configure WebAuthn`}
</a>`: html``}
</div>
</div>`;
}

View File

@ -72,7 +72,7 @@ export class UserForm extends Form<User> {
<ak-form-element-horizontal
label=${t`Attributes`}
name="attributes">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.user?.attributes)}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.user?.attributes, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -127,6 +127,13 @@ export class UserListPage extends TablePage<User> {
message: t`Successfully generated recovery link`,
description: rec.link
});
}).catch((ex: Response) => {
ex.json().then(() => {
showMessage({
level: MessageLevel.error,
message: t`No recovery flow is configured.`,
});
});
});
}}>
${t`Reset Password`}

View File

@ -6,6 +6,6 @@ Starting with 2021.3.5, every authentik instance has a built-in API browser, whi
To generate an API client, you can use the Swagger schema at https://authentik.company/api/v2beta/swagger.json.
While testing, the API requests are authenticated by your browser session. To send an API request from outside the browser, you need to set an `Authorization` header.
While testing, the API requests are authenticated by your browser session.
The value needs to be set to the base64-encoded token key.
To send an API request from outside the browser, you need to set the `Authorization` Header to `Bearer <your token>`.

View File

@ -1,5 +1,6 @@
---
title: Setting up a local dev environment
title: Getting started
slug: /
---
## Backend
@ -27,6 +28,10 @@ Afterwards, you can start authentik by running `./manage.py runserver`. Generall
Most functions and classes have type-hints and docstrings, so it is recommended to install a Python Type-checking Extension in your IDE to navigate around the code.
Before committing code, run `make lint` to ensure your code is formatted well. This also requires `pyright`, which can be installed with npm.
Run `make gen` to run all unittests and generated an updated swagger document for any changes you made.
## Frontend
By default, no transpiled bundle of the frontend is included. To build the UI, you need Node 12 or newer.
@ -54,3 +59,5 @@ npm run build
```
If you want to make changes to the UI, run `npm run watch` instead.
To ensure the code is formatted well, run `npx eslint . --fix` and `npm run lit-analyse`.

Some files were not shown because too many files have changed in this diff Show More