Compare commits

..

45 Commits

Author SHA1 Message Date
c621f62d92 release: 2021.2.2-stable 2021-02-10 13:33:23 +01:00
a0648cd925 build(deps-dev): bump typescript from 4.1.3 to 4.1.4 in /web (#544)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.1.3...v4.1.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-10 09:40:39 +01:00
2650e672bb build(deps): bump boto3 from 1.17.4 to 1.17.5 (#545)
Bumps [boto3](https://github.com/boto/boto3) from 1.17.4 to 1.17.5.
- [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.4...1.17.5)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-10 09:40:29 +01:00
53b9376789 build(deps): bump pycryptodome from 3.9.9 to 3.10.1 (#546)
Bumps [pycryptodome](https://github.com/Legrandin/pycryptodome) from 3.9.9 to 3.10.1.
- [Release notes](https://github.com/Legrandin/pycryptodome/releases)
- [Changelog](https://github.com/Legrandin/pycryptodome/blob/master/Changelog.rst)
- [Commits](https://github.com/Legrandin/pycryptodome/compare/v3.9.9...v3.10.1)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-10 09:39:50 +01:00
d15e50025c root: log runtime in milliseconds 2021-02-09 23:33:25 +01:00
0af66a26ab crypto: move certificate and key data to separate api calls to create events 2021-02-09 21:47:00 +01:00
bf754369d9 providers/proxy: fix certificates without key being selectable 2021-02-09 21:11:44 +01:00
02dc112f8f outposts: fix ProxyProvider update not triggering outpost update 2021-02-09 20:59:39 +01:00
2d4e7ebab5 admin: remove unnecessary success_urls 2021-02-09 20:58:46 +01:00
a7d0a50859 events: rename context.token to context.secret 2021-02-09 20:10:43 +01:00
71c9108f89 events: rename token_view to secret_view 2021-02-09 18:20:28 +01:00
f8bcdb26b3 web: PBResponse -> AKResponse 2021-02-09 17:04:55 +01:00
45f1d95bf9 sources/oauth: add callback URL to api 2021-02-09 16:58:19 +01:00
5dab198c47 web: add new sources view 2021-02-09 16:24:27 +01:00
ad91abe9de admin: remove old sources view 2021-02-09 16:17:48 +01:00
fa30755241 web: make ActionButton's method configurable 2021-02-09 16:14:51 +01:00
552f8c6a9a sources/*: switch API to use slug in URL 2021-02-09 16:08:30 +01:00
101f916247 web: add source list page 2021-02-09 10:22:49 +01:00
2acdcf74e1 sources/ldap: add API for sync status 2021-02-09 10:21:59 +01:00
ddb8610032 web: fix modalbutton for non-fetched sites 2021-02-09 10:00:33 +01:00
22ad850e6c web: fix overflow on modalbutton 2021-02-09 09:57:59 +01:00
57925ed60a build(deps-dev): bump @typescript-eslint/eslint-plugin in /web (#543)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.14.2 to 4.15.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.15.0/packages/eslint-plugin)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-09 09:57:06 +01:00
48cc2f17c1 build(deps-dev): bump @typescript-eslint/parser in /web (#542)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.14.2 to 4.15.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.15.0/packages/parser)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-09 09:30:41 +01:00
448108fca0 build(deps): bump boto3 from 1.17.3 to 1.17.4 (#541)
Bumps [boto3](https://github.com/boto/boto3) from 1.17.3 to 1.17.4.
- [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.3...1.17.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-09 09:30:30 +01:00
c1254f6212 web: update SiteShell to not use innerHTML 2021-02-08 23:16:20 +01:00
c8120c0d3e web: fix ModalButton working in global scope, causing issues on 2nd use 2021-02-08 23:10:45 +01:00
52016e0806 policies: skip cache on debug request 2021-02-08 22:14:23 +01:00
e555bdd42b lib: fix stacktrace for general expressions 2021-02-08 22:14:13 +01:00
1a619c90de Merge branch 'version-2021.2' 2021-02-08 21:51:59 +01:00
18faf30b0c docs: update release notes 2021-02-08 21:51:53 +01:00
b3bd979ecd release: 2021.2.1-stable 2021-02-08 21:34:05 +01:00
db113c5e8f Merge branch 'master' into version-2021.2 2021-02-08 21:33:58 +01:00
78bcb90a1e outposts: ensure Outpost API is backwards compatible 2021-02-08 19:51:46 +01:00
b64ecbde22 web: fix linting 2021-02-08 19:42:49 +01:00
43bab840ec web: fix sidebar being active when stage prompts is selected 2021-02-08 19:08:39 +01:00
f020b79384 admin: remove old code 2021-02-08 19:07:25 +01:00
820f658b49 web: add outpost list page 2021-02-08 19:04:19 +01:00
5d460a2537 admin: remove outposts list 2021-02-08 19:02:39 +01:00
efc46f52e6 outposts: move health to API 2021-02-08 19:01:10 +01:00
9fac51f8c7 outpost: downgrade recws for now
see https://github.com/recws-org/recws/issues/29
2021-02-08 17:56:58 +01:00
fe4b2d1a34 providers/oauth2: add authorized scopes to AUTHORIZE_APPLICATION event 2021-02-08 11:51:38 +01:00
f8abe3e210 providers/oauth2: add unofficial groups attribute to default profile claim 2021-02-08 11:50:26 +01:00
3ced67b151 sources/*: simplify source api 2021-02-08 10:25:59 +01:00
cd5631ec76 admin: fix link in source list 2021-02-08 10:25:59 +01:00
95df7c7f30 build(deps): bump construct-style-sheets-polyfill in /web (#540)
Bumps [construct-style-sheets-polyfill](https://github.com/calebdwilliams/adoptedStyleSheets) from 2.4.6 to 2.4.9.
- [Release notes](https://github.com/calebdwilliams/adoptedStyleSheets/releases)
- [Changelog](https://github.com/calebdwilliams/construct-style-sheets/blob/master/CHANGELOG.md)
- [Commits](https://github.com/calebdwilliams/adoptedStyleSheets/compare/v2.4.6...v2.4.9)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 09:22:59 +01:00
110 changed files with 1856 additions and 1077 deletions

View File

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

View File

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

174
Pipfile.lock generated
View File

@ -74,18 +74,17 @@
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:92041aa7589c886020cabd80eb58b89ace2f0094571792fccae24b9a8b3b97d7", "sha256:d6aafb804fca2b67c65dda78ad8b4afed901e004071208b84c804d345ad9ebba"
"sha256:9f132c34e20110dea019293c89cede49b0a56be615b3e1debf98390ed9f1f7b9"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.17.3" "version": "==1.17.5"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:1dae84c68b109f596f58cc2e9fa87704ccd40dcbc12144a89205f85efa7f9135", "sha256:04a1df759681f5f171accb354d863bfed0774d64a4e8ee35ff49835755660a4e",
"sha256:a0fdded1c9636899ab273f50bf123f79b91439a8c282b5face8b5f4a48b493cb" "sha256:3c55f0db5e08920727f4fa24a87aed60060643f4b0b5665c62ec762f79e82d6b"
], ],
"version": "==1.20.3" "version": "==1.20.5"
}, },
"cachetools": { "cachetools": {
"hashes": [ "hashes": [
@ -224,22 +223,15 @@
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d", "sha256:287032b6a7d86abc98e8e977b20138c53fea40e5b24e29090d5a675a973dcd10",
"sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7", "sha256:288c65eea20bd89b11102c47b118bc1e0749386b0a0dfebba414076c5d4c8188",
"sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901", "sha256:7eed937ad9b53280a5f53570d3a7dc93cb4412b6a3d58d4c6bb78cc26319c729",
"sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c", "sha256:dab437c2e84628703e3358f0f06555a6259bc5039209d51aa3b05af667ff4fd0",
"sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244", "sha256:ee5e19f0856b6fbbdbab15c2787ca65d203801d2d65d0b8de6218f424206c848",
"sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6", "sha256:f21be9ec6b44c223b2024bbe59d394fadc7be320d18a8d595419afadb6cd5620",
"sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5", "sha256:f6ea140d2736b7e1f0de4f988c43f76b0b3f3d365080e091715429ba218dce28"
"sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e",
"sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c",
"sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0",
"sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812",
"sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a",
"sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030",
"sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302"
], ],
"version": "==3.3.1" "version": "==3.4.4"
}, },
"dacite": { "dacite": {
"hashes": [ "hashes": [
@ -791,84 +783,74 @@
}, },
"pycryptodome": { "pycryptodome": {
"hashes": [ "hashes": [
"sha256:19cb674df6c74a14b8b408aa30ba8a89bd1c01e23505100fb45f930fbf0ed0d9", "sha256:09c1555a3fa450e7eaca41ea11cd00afe7c91fef52353488e65663777d8524e0",
"sha256:1cfdb92dca388e27e732caa72a1cc624520fe93752a665c3b6cd8f1a91b34916", "sha256:12222a5edc9ca4a29de15fbd5339099c4c26c56e13c2ceddf0b920794f26165d",
"sha256:27397aee992af69d07502126561d851ba3845aa808f0e55c71ad0efa264dd7d4", "sha256:1723ebee5561628ce96748501cdaa7afaa67329d753933296321f0be55358dce",
"sha256:28f75e58d02019a7edc7d4135203d2501dfc47256d175c72c9798f9a129a49a7", "sha256:1c5e1ca507de2ad93474be5cfe2bfa76b7cf039a1a32fc196f40935944871a06",
"sha256:2a68df525b387201a43b27b879ce8c08948a430e883a756d6c9e3acdaa7d7bd8", "sha256:2603c98ae04aac675fefcf71a6c87dc4bb74a75e9071ae3923bbc91a59f08d35",
"sha256:411745c6dce4eff918906eebcde78771d44795d747e194462abb120d2e537cd9", "sha256:2dea65df54349cdfa43d6b2e8edb83f5f8d6861e5cf7b1fbc3e34c5694c85e27",
"sha256:46e96aeb8a9ca8b1edf9b1fd0af4bf6afcf3f1ca7fa35529f5d60b98f3e4e959", "sha256:31c1df17b3dc5f39600a4057d7db53ac372f492c955b9b75dd439f5d8b460129",
"sha256:4ed27951b0a17afd287299e2206a339b5b6d12de9321e1a1575261ef9c4a851b", "sha256:38661348ecb71476037f1e1f553159b80d256c00f6c0b00502acac891f7116d9",
"sha256:50826b49fbca348a61529693b0031cdb782c39060fb9dca5ac5dff858159dc5a", "sha256:3e2e3a06580c5f190df843cdb90ea28d61099cf4924334d5297a995de68e4673",
"sha256:5598dc6c9dbfe882904e54584322893eff185b98960bbe2cdaaa20e8a437b6e5", "sha256:3f840c49d38986f6e17dbc0673d37947c88bc9d2d9dba1c01b979b36f8447db1",
"sha256:5c3c4865730dfb0263f822b966d6d58429d8b1e560d1ddae37685fd9e7c63161", "sha256:501ab36aae360e31d0ec370cf5ce8ace6cb4112060d099b993bc02b36ac83fb6",
"sha256:5f19e6ef750f677d924d9c7141f54bade3cd56695bbfd8a9ef15d0378557dfe4", "sha256:60386d1d4cfaad299803b45a5bc2089696eaf6cdd56f9fc17479a6f89595cfc8",
"sha256:60febcf5baf70c566d9d9351c47fbd8321da9a4edf2eff45c4c31c86164ca794", "sha256:6260e24d41149268122dd39d4ebd5941e9d107f49463f7e071fd397e29923b0c",
"sha256:62c488a21c253dadc9f731a32f0ac61e4e436d81a1ea6f7d1d9146ed4d20d6bd", "sha256:6bbf7fee7b7948b29d7e71fcacf48bac0c57fb41332007061a933f2d996f9713",
"sha256:6d3baaf82681cfb1a842f1c8f77beac791ceedd99af911e4f5fabec32bae2259", "sha256:6d2df5223b12437e644ce0a3be7809471ffa71de44ccd28b02180401982594a6",
"sha256:6e4227849e4231a3f5b35ea5bdedf9a82b3883500e5624f00a19156e9a9ef861", "sha256:758949ca62690b1540dfb24ad773c6da9cd0e425189e83e39c038bbd52b8e438",
"sha256:6e89bb3826e6f84501e8e3b205c22595d0c5492c2f271cbb9ee1c48eb1866645", "sha256:77997519d8eb8a4adcd9a47b9cec18f9b323e296986528186c0e9a7a15d6a07e",
"sha256:70d807d11d508433daf96244ec1c64e55039e8a35931fc5ea9eee94dbe3cb6b5", "sha256:7fd519b89585abf57bf47d90166903ec7b43af4fe23c92273ea09e6336af5c07",
"sha256:76b1a34d74bb2c91bce460cdc74d1347592045627a955e9a252554481c17c52f", "sha256:98213ac2b18dc1969a47bc65a79a8fca02a414249d0c8635abb081c7f38c91b6",
"sha256:7798e73225a699651888489fbb1dbc565e03a509942a8ce6194bbe6fb582a41f", "sha256:99b2f3fc51d308286071d0953f92055504a6ffe829a832a9fc7a04318a7683dd",
"sha256:834b790bbb6bd18956f625af4004d9c15eed12d5186d8e57851454ae76d52215", "sha256:9b6f711b25e01931f1c61ce0115245a23cdc8b80bf8539ac0363bdcf27d649b6",
"sha256:843e5f10ecdf9d307032b8b91afe9da1d6ed5bb89d0bbec5c8dcb4ba44008e11", "sha256:a3105a0eb63eacf98c2ecb0eb4aa03f77f40fbac2bdde22020bb8a536b226bb8",
"sha256:8f9f84059039b672a5a705b3c5aa21747867bacc30a72e28bf0d147cc8ef85ed", "sha256:a8eb8b6ea09ec1c2535bf39914377bc8abcab2c7d30fa9225eb4fe412024e427",
"sha256:9000877383e2189dafd1b2fc68c6c726eca9a3cfb6d68148fbb72ccf651959b6", "sha256:a92d5c414e8ee1249e850789052608f582416e82422502dc0ac8c577808a9067",
"sha256:910e202a557e1131b1c1b3f17a63914d57aac55cf9fb9b51644962841c3995c4", "sha256:d3d6958d53ad307df5e8469cc44474a75393a434addf20ecd451f38a72fe29b8",
"sha256:946399d15eccebafc8ce0257fc4caffe383c75e6b0633509bd011e357368306c", "sha256:e0a4d5933a88a2c98bbe19c0c722f5483dc628d7a38338ac2cb64a7dbd34064b",
"sha256:a199e9ca46fc6e999e5f47fce342af4b56c7de85fae893c69ab6aa17531fb1e1", "sha256:e3bf558c6aeb49afa9f0c06cee7fb5947ee5a1ff3bd794b653d39926b49077fa",
"sha256:a3d8a9efa213be8232c59cdc6b65600276508e375e0a119d710826248fd18d37", "sha256:e61e363d9a5d7916f3a4ce984a929514c0df3daf3b1b2eb5e6edbb131ee771cf",
"sha256:a4599c0ca0fc027c780c1c45ed996d5bef03e571470b7b1c7171ec1e1a90914c", "sha256:f977cdf725b20f6b8229b0c87acb98c7717e742ef9f46b113985303ae12a99da",
"sha256:b4e6b269a8ddaede774e5c3adbef6bf452ee144e6db8a716d23694953348cd86", "sha256:fc7489a50323a0df02378bc2fff86eb69d94cc5639914346c736be981c6a02e7"
"sha256:b68794fba45bdb367eeb71249c26d23e61167510a1d0c3d6cf0f2f14636e62ee",
"sha256:d7ec2bd8f57c559dd24e71891c51c25266a8deb66fc5f02cc97c7fb593d1780a",
"sha256:e15bde67ccb7d4417f627dd16ffe2f5a4c2941ce5278444e884cb26d73ecbc61",
"sha256:eb01f9997e4d6a8ec8a1ad1f676ba5a362781ff64e8189fe2985258ba9cb9706",
"sha256:faa682c404c218e8788c3126c9a4b8fbcc54dc245b5b6e8ea5b46f3b63bd0c84"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.9.9" "version": "==3.10.1"
}, },
"pycryptodomex": { "pycryptodomex": {
"hashes": [ "hashes": [
"sha256:15c03ffdac17731b126880622823d30d0a3cc7203cd219e6b9814140a44e7fab", "sha256:00a584ee52bf5e27d540129ca9bf7c4a7e7447f24ff4a220faa1304ad0c09bcd",
"sha256:20fb7f4efc494016eab1bc2f555bc0a12dd5ca61f35c95df8061818ffb2c20a3", "sha256:04265a7a84ae002001249bd1de2823bcf46832bd4b58f6965567cb8a07cf4f00",
"sha256:28ee3bcb4d609aea3040cad995a8e2c9c6dc57c12183dadd69e53880c35333b9", "sha256:0bd35af6a18b724c689e56f2dbbdd8e409288be71952d271ba3d9614b31d188c",
"sha256:305e3c46f20d019cd57543c255e7ba49e432e275d7c0de8913b6dbe57a851bc8", "sha256:20c45a30f3389148f94edb77f3b216c677a277942f62a2b81a1cc0b6b2dde7fc",
"sha256:3547b87b16aad6afb28c9b3a9cd870e11b5e7b5ac649b74265258d96d8de1130", "sha256:2959304d1ce31ab303d9fb5db2b294814278b35154d9b30bf7facc52d6088d0a",
"sha256:3642252d7bfc4403a42050e18ba748bedebd5a998a8cba89665a4f42aea4c380", "sha256:36dab7f506948056ceba2d57c1ade74e898401960de697cefc02f3519bd26c1b",
"sha256:404faa3e518f8bea516aae2aac47d4d960397199a15b4bd6f66cad97825469a0", "sha256:37ec1b407ec032c7a0c1fdd2da12813f560bad38ae61ad9c7ce3c0573b3e5e30",
"sha256:42669638e4f7937b7141044a2fbd1019caca62bd2cdd8b535f731426ab07bde1", "sha256:3b8eb85b3cc7f083d87978c264d10ff9de3b4bfc46f1c6fdc2792e7d7ebc87bb",
"sha256:4632d55a140b28e20be3cd7a3057af52fb747298ff0fd3290d4e9f245b5004ba", "sha256:3dfce70c4e425607ae87b8eae67c9c7dbba59a33b62d70f79417aef0bc5c735b",
"sha256:4a88c9383d273bdce3afc216020282c9c5c39ec0bd9462b1a206af6afa377cf0", "sha256:418f51c61eab52d9920f4ef468d22c89dab1be5ac796f71cf3802f6a6e667df0",
"sha256:4ce1fc1e6d2fd2d6dc197607153327989a128c093e0e94dca63408f506622c3e", "sha256:4195604f75cdc1db9bccdb9e44d783add3c817319c30aaff011670c9ed167690",
"sha256:55cf4e99b3ba0122dee570dc7661b97bf35c16aab3e2ccb5070709d282a1c7ab", "sha256:4344ab16faf6c2d9df2b6772995623698fb2d5f114dace4ab2ff335550cf71d5",
"sha256:5e486cab2dfcfaec934dd4f5d5837f4a9428b690f4d92a3b020fd31d1497ca64", "sha256:541cd3e3e252fb19a7b48f420b798b53483302b7fe4d9954c947605d0a263d62",
"sha256:65ec88c8271448d2ea109d35c1f297b09b872c57214ab7e832e413090d3469a9", "sha256:564063e3782474c92cbb333effd06e6eb718471783c6e67f28c63f0fc3ac7b23",
"sha256:6c95a3361ce70068cf69526a58751f73ddac5ba27a3c2379b057efa2f5338c8c", "sha256:72f44b5be46faef2a1bf2a85902511b31f4dd7b01ce0c3978e92edb2cc812a82",
"sha256:73240335f4a1baf12880ebac6df66ab4d3a9212db9f3efe809c36a27280d16f8", "sha256:8a98e02cbf8f624add45deff444539bf26345b479fc04fa0937b23cd84078d91",
"sha256:7651211e15109ac0058a49159265d9f6e6423c8a81c65434d3c56d708417a05b", "sha256:940db96449d7b2ebb2c7bf190be1514f3d67914bd37e54e8d30a182bd375a1a9",
"sha256:7b5b7c5896f8172ea0beb283f7f9428e0ab88ec248ce0a5b8c98d73e26267d51", "sha256:961333e7ee896651f02d4692242aa36b787b8e8e0baa2256717b2b9d55ae0a3c",
"sha256:836fe39282e75311ce4c38468be148f7fac0df3d461c5de58c5ff1ddb8966bac", "sha256:9f713ffb4e27b5575bd917c70bbc3f7b348241a351015dbbc514c01b7061ff7e",
"sha256:871852044f55295449fbf225538c2c4118525093c32f0a6c43c91bed0452d7e3", "sha256:a6584ae58001d17bb4dc0faa8a426919c2c028ef4d90ceb4191802ca6edb8204",
"sha256:892e93f3e7e10c751d6c17fa0dc422f7984cfd5eb6690011f9264dc73e2775fc", "sha256:c2b680987f418858e89dbb4f09c8c919ece62811780a27051ace72b2f69fb1be",
"sha256:934e460c5058346c6f1d62fdf3db5680fbdfbfd212722d24d8277bf47cd9ebdc", "sha256:d8fae5ba3d34c868ae43614e0bd6fb61114b2687ac3255798791ce075d95aece",
"sha256:9736f3f3e1761024200637a080a4f922f5298ad5d780e10dbb5634fe8c65b34c", "sha256:dbd2c361db939a4252589baa94da4404d45e3fc70da1a31e541644cdf354336e",
"sha256:a1d38a96da57e6103423a446079ead600b450cf0f8ebf56a231895abf77e7ffc", "sha256:e090a8609e2095aa86978559b140cf8968af99ee54b8791b29ff804838f29f10",
"sha256:a385fceaa0cdb97f0098f1c1e9ec0b46cc09186ddf60ec23538e871b1dddb6dc", "sha256:e4a1245e7b846e88ba63e7543483bda61b9acbaee61eadbead5a1ce479d94740",
"sha256:a7cf1c14e47027d9fb9d26aa62e5d603994227bd635e58a8df4b1d2d1b6a8ed7", "sha256:ec9901d19cadb80d9235ee41cc58983f18660314a0eb3fc7b11b0522ac3b6c4a",
"sha256:a9aac1a30b00b5038d3d8e48248f3b58ea15c827b67325c0d18a447552e30fc8", "sha256:f2abeb4c4ce7584912f4d637b2c57f23720d35dd2892bfeb1b2c84b6fb7a8c88",
"sha256:b696876ee583d15310be57311e90e153a84b7913ac93e6b99675c0c9867926d0", "sha256:f3bb267df679f70a9f40f17d62d22fe12e8b75e490f41807e7560de4d3e6bf9f",
"sha256:bef9e9d39393dc7baec39ba4bac6c73826a4db02114cdeade2552a9d6afa16e2", "sha256:f933ecf4cb736c7af60a6a533db2bf569717f2318b265f92907acff1db43bc34",
"sha256:c885fe4d5f26ce8ca20c97d02e88f5fdd92c01e1cc771ad0951b21e1641faf6d", "sha256:fc9c55dc1ed57db76595f2d19a479fc1c3a1be2c9da8de798a93d286c5f65f38"
"sha256:d2d1388595cb5d27d9220d5cbaff4f37c6ec696a25882eb06d224d241e6e93fb",
"sha256:d2e853e0f9535e693fade97768cf7293f3febabecc5feb1e9b2ffdfe1044ab96",
"sha256:d62fbab185a6b01c5469eda9f0795f3d1a5bba24f5a5813f362e4b73a3c4dc70",
"sha256:f20a62397e09704049ce9007bea4f6bad965ba9336a760c6f4ef1b4192e12d6d",
"sha256:f81f7311250d9480e36dec819127897ae772e7e8de07abfabe931b8566770b8e"
], ],
"version": "==3.9.9" "version": "==3.10.1"
}, },
"pyhamcrest": { "pyhamcrest": {
"hashes": [ "hashes": [
@ -1446,10 +1428,10 @@
}, },
"gitpython": { "gitpython": {
"hashes": [ "hashes": [
"sha256:42dbefd8d9e2576c496ed0059f3103dcef7125b9ce16f9d5f9c834aed44a1dac", "sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a",
"sha256:867ec3dfb126aac0f8296b19fb63b8c4a399f32b4b6fafe84c4b10af5fa9f7b5" "sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29"
], ],
"version": "==3.1.12" "version": "==3.1.13"
}, },
"iniconfig": { "iniconfig": {
"hashes": [ "hashes": [

View File

@ -1,2 +1,2 @@
"""authentik""" """authentik"""
__version__ = "2021.2.1-rc2" __version__ = "2021.2.2-stable"

View File

@ -1,19 +0,0 @@
"""authentik core source form fields"""
SOURCE_FORM_FIELDS = [
"name",
"slug",
"enabled",
"authentication_flow",
"enrollment_flow",
]
SOURCE_SERIALIZER_FIELDS = [
"pk",
"name",
"slug",
"enabled",
"authentication_flow",
"enrollment_flow",
"verbose_name",
"verbose_name_plural",
]

View File

@ -1,149 +0,0 @@
{% extends "administration/base.html" %}
{% load i18n %}
{% load humanize %}
{% load authentik_utils %}
{% load admin_reflection %}
{% block content %}
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-zone"></i>
{% trans 'Outposts' %}
</h1>
<p>{% trans "Outposts are deployments of authentik components to support different environments and protocols, like reverse proxies." %}</p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
<div class="pf-c-toolbar__bulk-select">
<ak-modal-button href="{% url 'authentik_admin:outpost-create' %}">
<ak-spinner-button slot="trigger" class="pf-m-primary">
{% trans 'Create' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
<button role="ak-refresh" class="pf-c-button pf-m-primary">
{% trans 'Refresh' %}
</button>
</div>
{% include 'partials/pagination.html' %}
</div>
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
<tr role="row">
<th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th role="columnheader" scope="col">{% trans 'Providers' %}</th>
<th role="columnheader" scope="col">{% trans 'Health' %}</th>
<th role="columnheader" scope="col">{% trans 'Version' %}</th>
<th role="cell"></th>
</tr>
</thead>
<tbody role="rowgroup">
{% for outpost in object_list %}
<tr role="row">
<th role="columnheader">
<span>{{ outpost.name }}</span>
</th>
<td role="cell">
<span>
{{ outpost.providers.all.select_subclasses|join:", " }}
</span>
</td>
{% with states=outpost.state %}
{% if states|length > 0 %}
<td role="cell">
{% for state in states %}
<div>
{% if state.last_seen %}
<i class="fas fa-check pf-m-success"></i> {{ state.last_seen|naturaltime }}
{% else %}
<i class="fas fa-times pf-m-danger"></i> {% trans 'Unhealthy' %}
{% endif %}
</div>
{% endfor %}
</td>
<td role="cell">
{% for state in states %}
<div>
{% if not state.version %}
<i class="fas fa-question-circle"></i>
{% elif state.version_outdated %}
<i class="fas fa-times pf-m-danger"></i> {% blocktrans with is=state.version should=state.version_should %}{{ is }}, should be {{ should }}{% endblocktrans %}
{% else %}
<i class="fas fa-check pf-m-success"></i> {{ state.version }}
{% endif %}
</div>
{% endfor %}
</td>
{% else %}
<td role="cell">
<i class="fas fa-question-circle"></i>
</td>
<td role="cell">
<i class="fas fa-question-circle"></i>
</td>
{% endif %}
{% endwith %}
<td>
<ak-modal-button href="{% url 'authentik_admin:outpost-update' pk=outpost.pk %}">
<ak-spinner-button slot="trigger" class="pf-m-secondary">
{% trans 'Edit' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
<ak-modal-button href="{% url 'authentik_admin:outpost-delete' pk=outpost.pk %}">
<ak-spinner-button slot="trigger" class="pf-m-danger">
{% trans 'Delete' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
{% get_htmls outpost as htmls %}
{% for html in htmls %}
{{ html|safe }}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pf-c-pagination pf-m-bottom">
{% include 'partials/pagination.html' %}
</div>
{% else %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
</div>
</div>
<div class="pf-c-empty-state">
<div class="pf-c-empty-state__content">
<i class="fas fa-map-marker pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Outposts.' %}
</h1>
<div class="pf-c-empty-state__body">
{% if request.GET.search != "" %}
{% trans "Your search query doesn't match any outposts." %}
{% else %}
{% trans 'Currently no outposts exist. Click the button below to create one.' %}
{% endif %}
</div>
<ak-modal-button href="{% url 'authentik_admin:outpost-create' %}">
<ak-spinner-button slot="trigger" class="pf-m-primary">
{% trans 'Create' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
</div>
</div>
{% endif %}
</div>
</section>
{% endblock %}

View File

@ -3,7 +3,6 @@
{% load i18n %} {% load i18n %}
{% load humanize %} {% load humanize %}
{% load authentik_utils %} {% load authentik_utils %}
{% load admin_reflection %}
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light"> <section class="pf-c-page__main-section pf-m-light">

View File

@ -1,139 +0,0 @@
{% extends "administration/base.html" %}
{% load i18n %}
{% load authentik_utils %}
{% block content %}
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-blueprint"></i>
{% trans 'Property Mappings' %}
</h1>
<p>{% trans "Control how authentik exposes and interprets information." %}
</p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
<div class="pf-c-toolbar__bulk-select">
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<ak-modal-button href="{% url 'authentik_admin:property-mapping-create' %}?type={{ type }}">
<button slot="trigger" class="pf-c-dropdown__menu-item">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</button>
<div slot="modal"></div>
</ak-modal-button>
</li>
{% endfor %}
</ul>
</ak-dropdown>
<button role="ak-refresh" class="pf-c-button pf-m-primary">
{% trans 'Refresh' %}
</button>
</div>
{% include 'partials/pagination.html' %}
</div>
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
<tr role="row">
<th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th role="columnheader" scope="col">{% trans 'Type' %}</th>
<th role="cell"></th>
</tr>
</thead>
<tbody role="rowgroup">
{% for property_mapping in object_list %}
<tr role="row">
<td role="cell">
<span>
{{ property_mapping.name }}
</span>
</td>
<td role="cell">
<span>
{{ property_mapping|verbose_name }}
</span>
</td>
<td>
<ak-modal-button href="{% url 'authentik_admin:property-mapping-update' pk=property_mapping.pk %}">
<ak-spinner-button slot="trigger" class="pf-m-secondary">
{% trans 'Edit' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
<ak-modal-button href="{% url 'authentik_admin:property-mapping-delete' pk=property_mapping.pk %}">
<ak-spinner-button slot="trigger" class="pf-m-danger">
{% trans 'Delete' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pf-c-pagination pf-m-bottom">
{% include 'partials/pagination.html' %}
</div>
{% else %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
</div>
</div>
<div class="pf-c-empty-state">
<div class="pf-c-empty-state__content">
<i class="pf-icon pf-icon-blueprint pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Property Mappings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% if request.GET.search != "" %}
{% trans "Your search query doesn't match any property mappings." %}
{% else %}
{% trans 'Currently no property mappings exist. Click the button below to create one.' %}
{% endif %}
</div>
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<ak-modal-button href="{% url 'authentik_admin:property-mapping-create' %}?type={{ type }}">
<button slot="trigger" class="pf-c-dropdown__menu-item">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</button>
<div slot="modal"></div>
</ak-modal-button>
</li>
{% endfor %}
</ul>
</ak-dropdown>
</div>
</div>
{% endif %}
</div>
</section>
{% endblock %}

View File

@ -2,7 +2,6 @@
{% load i18n %} {% load i18n %}
{% load authentik_utils %} {% load authentik_utils %}
{% load admin_reflection %}
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light"> <section class="pf-c-page__main-section pf-m-light">
@ -63,7 +62,7 @@
{% for source in object_list %} {% for source in object_list %}
<tr role="row"> <tr role="row">
<th role="columnheader"> <th role="columnheader">
<a href="/sources/{{ source.slug }}/"> <a href="/sources/{{ source.slug }}">
<div>{{ source.name }}</div> <div>{{ source.name }}</div>
{% if not source.enabled %} {% if not source.enabled %}
<small>{% trans 'Disabled' %}</small> <small>{% trans 'Disabled' %}</small>
@ -93,10 +92,6 @@
</ak-spinner-button> </ak-spinner-button>
<div slot="modal"></div> <div slot="modal"></div>
</ak-modal-button> </ak-modal-button>
{% get_links source as links %}
{% for name, href in links %}
<a class="pf-c-button pf-m-tertiary ak-root-link" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -2,7 +2,6 @@
{% load i18n %} {% load i18n %}
{% load authentik_utils %} {% load authentik_utils %}
{% load admin_reflection %}
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light"> <section class="pf-c-page__main-section pf-m-light">
@ -88,10 +87,6 @@
</ak-spinner-button> </ak-spinner-button>
<div slot="modal"></div> <div slot="modal"></div>
</ak-modal-button> </ak-modal-button>
{% get_links stage as links %}
{% for name, href in links.items %}
<a class="pf-c-button pf-m-tertiary ak-root-link" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -2,7 +2,6 @@
{% load i18n %} {% load i18n %}
{% load authentik_utils %} {% load authentik_utils %}
{% load admin_reflection %}
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light"> <section class="pf-c-page__main-section pf-m-light">
@ -90,10 +89,6 @@
</ak-spinner-button> </ak-spinner-button>
<div slot="modal"></div> <div slot="modal"></div>
</ak-modal-button> </ak-modal-button>
{% get_links prompt as links %}
{% for name, href in links.items %}
<a class="pf-c-button pf-m-tertiary ak-root-link" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -1,62 +0,0 @@
"""authentik admin templatetags"""
from django import template
from django.db.models import Model
from django.utils.html import mark_safe
from structlog.stdlib import get_logger
register = template.Library()
LOGGER = get_logger()
@register.simple_tag()
def get_links(model_instance):
"""Find all link_ methods on an object instance, run them and return as dict"""
prefix = "link_"
links = {}
if not isinstance(model_instance, Model):
LOGGER.warning("Model is not instance of Model", model_instance=model_instance)
return links
try:
for name in dir(model_instance):
if not name.startswith(prefix):
continue
value = getattr(model_instance, name)
if not callable(value):
continue
human_name = name.replace(prefix, "").replace("_", " ").capitalize()
link = value()
if link:
links[human_name] = link
except NotImplementedError:
pass
return links
@register.simple_tag(takes_context=True)
def get_htmls(context, model_instance):
"""Find all html_ methods on an object instance, run them and return as dict"""
prefix = "html_"
htmls = []
if not isinstance(model_instance, Model):
LOGGER.warning("Model is not instance of Model", model_instance=model_instance)
return htmls
try:
for name in dir(model_instance):
if not name.startswith(prefix):
continue
value = getattr(model_instance, name)
if not callable(value):
continue
if name.startswith(prefix):
html = value(context.get("request"))
if html:
htmls.append(mark_safe(html))
except NotImplementedError:
pass
return htmls

View File

@ -61,7 +61,6 @@ urlpatterns = [
name="token-delete", name="token-delete",
), ),
# Sources # Sources
path("sources/", sources.SourceListView.as_view(), name="sources"),
path("sources/create/", sources.SourceCreateView.as_view(), name="source-create"), path("sources/create/", sources.SourceCreateView.as_view(), name="source-create"),
path( path(
"sources/<uuid:pk>/update/", "sources/<uuid:pk>/update/",
@ -169,22 +168,22 @@ urlpatterns = [
), ),
# Stage Prompts # Stage Prompts
path( path(
"stages/prompts/", "stages_prompts/",
stages_prompts.PromptListView.as_view(), stages_prompts.PromptListView.as_view(),
name="stage-prompts", name="stage-prompts",
), ),
path( path(
"stages/prompts/create/", "stages_prompts/create/",
stages_prompts.PromptCreateView.as_view(), stages_prompts.PromptCreateView.as_view(),
name="stage-prompt-create", name="stage-prompt-create",
), ),
path( path(
"stages/prompts/<uuid:pk>/update/", "stages_prompts/<uuid:pk>/update/",
stages_prompts.PromptUpdateView.as_view(), stages_prompts.PromptUpdateView.as_view(),
name="stage-prompt-update", name="stage-prompt-update",
), ),
path( path(
"stages/prompts/<uuid:pk>/delete/", "stages_prompts/<uuid:pk>/delete/",
stages_prompts.PromptDeleteView.as_view(), stages_prompts.PromptDeleteView.as_view(),
name="stage-prompt-delete", name="stage-prompt-delete",
), ),
@ -311,11 +310,6 @@ urlpatterns = [
name="certificatekeypair-delete", name="certificatekeypair-delete",
), ),
# Outposts # Outposts
path(
"outposts/",
outposts.OutpostListView.as_view(),
name="outposts",
),
path( path(
"outposts/create/", "outposts/create/",
outposts.OutpostCreateView.as_view(), outposts.OutpostCreateView.as_view(),

View File

@ -4,7 +4,6 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import UpdateView from django.views.generic import UpdateView
from guardian.mixins import PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
@ -29,7 +28,6 @@ class ApplicationCreateView(
permission_required = "authentik_core.add_application" permission_required = "authentik_core.add_application"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully created Application") success_message = _("Successfully created Application")
@ -47,7 +45,6 @@ class ApplicationUpdateView(
permission_required = "authentik_core.change_application" permission_required = "authentik_core.change_application"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully updated Application") success_message = _("Successfully updated Application")
@ -60,5 +57,4 @@ class ApplicationDeleteView(
permission_required = "authentik_core.delete_application" permission_required = "authentik_core.delete_application"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully deleted Application") success_message = _("Successfully deleted Application")

View File

@ -4,7 +4,6 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import UpdateView from django.views.generic import UpdateView
from guardian.mixins import PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
@ -29,7 +28,6 @@ class NotificationRuleCreateView(
permission_required = "authentik_events.add_NotificationRule" permission_required = "authentik_events.add_NotificationRule"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully created Notification Rule") success_message = _("Successfully created Notification Rule")
@ -47,7 +45,6 @@ class NotificationRuleUpdateView(
permission_required = "authentik_events.change_NotificationRule" permission_required = "authentik_events.change_NotificationRule"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully updated Notification Rule") success_message = _("Successfully updated Notification Rule")
@ -60,5 +57,4 @@ class NotificationRuleDeleteView(
permission_required = "authentik_events.delete_NotificationRule" permission_required = "authentik_events.delete_NotificationRule"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully deleted Notification Rule") success_message = _("Successfully deleted Notification Rule")

View File

@ -4,7 +4,6 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import UpdateView from django.views.generic import UpdateView
from guardian.mixins import PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
@ -29,7 +28,6 @@ class NotificationTransportCreateView(
permission_required = "authentik_events.add_notificationtransport" permission_required = "authentik_events.add_notificationtransport"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully created Notification Transport") success_message = _("Successfully created Notification Transport")
@ -47,7 +45,6 @@ class NotificationTransportUpdateView(
permission_required = "authentik_events.change_notificationtransport" permission_required = "authentik_events.change_notificationtransport"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully updated Notification Transport") success_message = _("Successfully updated Notification Transport")
@ -60,5 +57,4 @@ class NotificationTransportDeleteView(
permission_required = "authentik_events.delete_notificationtransport" permission_required = "authentik_events.delete_notificationtransport"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully deleted Notification Transport") success_message = _("Successfully deleted Notification Transport")

View File

@ -7,38 +7,16 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import ListView, UpdateView from django.views.generic import UpdateView
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
from authentik.admin.views.utils import ( from authentik.admin.views.utils import BackSuccessUrlMixin, DeleteMessageView
BackSuccessUrlMixin,
DeleteMessageView,
SearchListMixin,
UserPaginateListMixin,
)
from authentik.lib.views import CreateAssignPermView from authentik.lib.views import CreateAssignPermView
from authentik.outposts.forms import OutpostForm from authentik.outposts.forms import OutpostForm
from authentik.outposts.models import Outpost, OutpostConfig from authentik.outposts.models import Outpost, OutpostConfig
class OutpostListView(
LoginRequiredMixin,
PermissionListMixin,
UserPaginateListMixin,
SearchListMixin,
ListView,
):
"""Show list of all outposts"""
model = Outpost
permission_required = "authentik_outposts.view_outpost"
ordering = "name"
template_name = "administration/outpost/list.html"
search_fields = ["name", "_config"]
class OutpostCreateView( class OutpostCreateView(
SuccessMessageMixin, SuccessMessageMixin,
BackSuccessUrlMixin, BackSuccessUrlMixin,
@ -53,7 +31,6 @@ class OutpostCreateView(
permission_required = "authentik_outposts.add_outpost" permission_required = "authentik_outposts.add_outpost"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_admin:outposts")
success_message = _("Successfully created Outpost") success_message = _("Successfully created Outpost")
def get_initial(self) -> Dict[str, Any]: def get_initial(self) -> Dict[str, Any]:
@ -78,7 +55,6 @@ class OutpostUpdateView(
permission_required = "authentik_outposts.change_outpost" permission_required = "authentik_outposts.change_outpost"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_admin:outposts")
success_message = _("Successfully updated Outpost") success_message = _("Successfully updated Outpost")
@ -89,5 +65,4 @@ class OutpostDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessa
permission_required = "authentik_outposts.delete_outpost" permission_required = "authentik_outposts.delete_outpost"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_admin:outposts")
success_message = _("Successfully deleted Outpost") success_message = _("Successfully deleted Outpost")

View File

@ -3,7 +3,6 @@ from django.contrib.messages.views import SuccessMessageMixin
from django.core.cache import cache from django.core.cache import cache
from django.http.request import HttpRequest from django.http.request import HttpRequest
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.urls.base import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import FormView from django.views.generic import FormView
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -21,7 +20,6 @@ class PolicyCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
form_class = PolicyCacheClearForm form_class = PolicyCacheClearForm
template_name = "generic/form_non_model.html" template_name = "generic/form_non_model.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully cleared Policy cache") success_message = _("Successfully cleared Policy cache")
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
@ -40,7 +38,6 @@ class FlowCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
form_class = FlowCacheClearForm form_class = FlowCacheClearForm
template_name = "generic/form_non_model.html" template_name = "generic/form_non_model.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully cleared Flow cache") success_message = _("Successfully cleared Flow cache")
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:

View File

@ -8,7 +8,6 @@ from django.contrib.auth.mixins import (
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpResponse from django.http import HttpResponse
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import FormView from django.views.generic import FormView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
@ -37,7 +36,6 @@ class PropertyMappingCreateView(
permission_required = "authentik_core.add_propertymapping" permission_required = "authentik_core.add_propertymapping"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully created Property Mapping") success_message = _("Successfully created Property Mapping")
@ -54,7 +52,6 @@ class PropertyMappingUpdateView(
permission_required = "authentik_core.change_propertymapping" permission_required = "authentik_core.change_propertymapping"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully updated Property Mapping") success_message = _("Successfully updated Property Mapping")
@ -67,7 +64,6 @@ class PropertyMappingDeleteView(
permission_required = "authentik_core.delete_propertymapping" permission_required = "authentik_core.delete_propertymapping"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_core:shell")
success_message = _("Successfully deleted Property Mapping") success_message = _("Successfully deleted Property Mapping")

View File

@ -4,7 +4,6 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from guardian.mixins import PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
@ -30,7 +29,6 @@ class ProviderCreateView(
permission_required = "authentik_core.add_provider" permission_required = "authentik_core.add_provider"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_admin:providers")
success_message = _("Successfully created Provider") success_message = _("Successfully created Provider")
@ -47,7 +45,6 @@ class ProviderUpdateView(
permission_required = "authentik_core.change_provider" permission_required = "authentik_core.change_provider"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_admin:providers")
success_message = _("Successfully updated Provider") success_message = _("Successfully updated Provider")
@ -60,5 +57,4 @@ class ProviderDeleteView(
permission_required = "authentik_core.delete_provider" permission_required = "authentik_core.delete_provider"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_admin:providers")
success_message = _("Successfully deleted Provider") success_message = _("Successfully deleted Provider")

View File

@ -4,38 +4,18 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
from authentik.admin.views.utils import ( from authentik.admin.views.utils import (
BackSuccessUrlMixin, BackSuccessUrlMixin,
DeleteMessageView, DeleteMessageView,
InheritanceCreateView, InheritanceCreateView,
InheritanceListView,
InheritanceUpdateView, InheritanceUpdateView,
SearchListMixin,
UserPaginateListMixin,
) )
from authentik.core.models import Source from authentik.core.models import Source
class SourceListView(
LoginRequiredMixin,
PermissionListMixin,
UserPaginateListMixin,
SearchListMixin,
InheritanceListView,
):
"""Show list of all sources"""
model = Source
permission_required = "authentik_core.view_source"
ordering = "name"
template_name = "administration/source/list.html"
search_fields = ["name", "slug"]
class SourceCreateView( class SourceCreateView(
SuccessMessageMixin, SuccessMessageMixin,
BackSuccessUrlMixin, BackSuccessUrlMixin,
@ -49,7 +29,6 @@ class SourceCreateView(
permission_required = "authentik_core.add_source" permission_required = "authentik_core.add_source"
template_name = "generic/create.html" template_name = "generic/create.html"
success_url = reverse_lazy("authentik_admin:sources")
success_message = _("Successfully created Source") success_message = _("Successfully created Source")
@ -66,7 +45,6 @@ class SourceUpdateView(
permission_required = "authentik_core.change_source" permission_required = "authentik_core.change_source"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_admin:sources")
success_message = _("Successfully updated Source") success_message = _("Successfully updated Source")
@ -77,5 +55,4 @@ class SourceDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessag
permission_required = "authentik_core.delete_source" permission_required = "authentik_core.delete_source"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("authentik_admin:sources")
success_message = _("Successfully deleted Source") success_message = _("Successfully deleted Source")

View File

@ -29,11 +29,12 @@ from authentik.flows.api import (
FlowViewSet, FlowViewSet,
StageViewSet, StageViewSet,
) )
from authentik.outposts.api import ( from authentik.outposts.api.outpost_service_connections import (
DockerServiceConnectionViewSet, DockerServiceConnectionViewSet,
KubernetesServiceConnectionViewSet, KubernetesServiceConnectionViewSet,
OutpostViewSet, ServiceConnectionViewSet,
) )
from authentik.outposts.api.outposts import OutpostViewSet
from authentik.policies.api import ( from authentik.policies.api import (
PolicyBindingViewSet, PolicyBindingViewSet,
PolicyCacheViewSet, PolicyCacheViewSet,
@ -88,6 +89,7 @@ router.register("core/users", UserViewSet)
router.register("core/tokens", TokenViewSet) router.register("core/tokens", TokenViewSet)
router.register("outposts/outposts", OutpostViewSet) router.register("outposts/outposts", OutpostViewSet)
router.register("outposts/service_connections/all", ServiceConnectionViewSet)
router.register("outposts/service_connections/docker", DockerServiceConnectionViewSet) router.register("outposts/service_connections/docker", DockerServiceConnectionViewSet)
router.register( router.register(
"outposts/service_connections/kubernetes", KubernetesServiceConnectionViewSet "outposts/service_connections/kubernetes", KubernetesServiceConnectionViewSet

View File

@ -2,7 +2,6 @@
from rest_framework.serializers import ModelSerializer, SerializerMethodField from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet
from authentik.admin.forms.source import SOURCE_SERIALIZER_FIELDS
from authentik.core.api.utils import MetaNameSerializer from authentik.core.api.utils import MetaNameSerializer
from authentik.core.models import Source from authentik.core.models import Source
@ -10,22 +9,26 @@ from authentik.core.models import Source
class SourceSerializer(ModelSerializer, MetaNameSerializer): class SourceSerializer(ModelSerializer, MetaNameSerializer):
"""Source Serializer""" """Source Serializer"""
__type__ = SerializerMethodField(method_name="get_type") object_type = SerializerMethodField()
def get_type(self, obj): def get_object_type(self, obj):
"""Get object type so that we know which API Endpoint to use to get the full object""" """Get object type so that we know which API Endpoint to use to get the full object"""
return obj._meta.object_name.lower().replace("source", "") return obj._meta.object_name.lower().replace("source", "")
def to_representation(self, instance: Source):
# pyright: reportGeneralTypeIssues=false
if instance.__class__ == Source:
return super().to_representation(instance)
return instance.serializer(instance=instance).data
class Meta: class Meta:
model = Source model = Source
fields = SOURCE_SERIALIZER_FIELDS + ["__type__"] fields = SOURCE_SERIALIZER_FIELDS = [
"pk",
"name",
"slug",
"enabled",
"authentication_flow",
"enrollment_flow",
"object_type",
"verbose_name",
"verbose_name_plural",
]
class SourceViewSet(ReadOnlyModelViewSet): class SourceViewSet(ReadOnlyModelViewSet):

View File

@ -1,9 +1,12 @@
"""Tokens API Viewset""" """Tokens API Viewset"""
from django.db.models.base import Model
from django.http.response import Http404 from django.http.response import Http404
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import CharField
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer, Serializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.core.models import Token from authentik.core.models import Token
@ -19,6 +22,18 @@ class TokenSerializer(ModelSerializer):
fields = ["pk", "identifier", "intent", "user", "description"] fields = ["pk", "identifier", "intent", "user", "description"]
class TokenViewSerializer(Serializer):
"""Show token's current key"""
key = CharField(read_only=True)
def create(self, validated_data: dict) -> Model:
raise NotImplementedError
def update(self, instance: Model, validated_data: dict) -> Model:
raise NotImplementedError
class TokenViewSet(ModelViewSet): class TokenViewSet(ModelViewSet):
"""Token Viewset""" """Token Viewset"""
@ -26,6 +41,7 @@ class TokenViewSet(ModelViewSet):
queryset = Token.filter_not_expired() queryset = Token.filter_not_expired()
serializer_class = TokenSerializer serializer_class = TokenSerializer
@swagger_auto_schema(responses={200: TokenViewSerializer(many=False)})
@action(detail=True) @action(detail=True)
def view_key(self, request: Request, identifier: str) -> Response: def view_key(self, request: Request, identifier: str) -> Response:
"""Return token key and log access""" """Return token key and log access"""
@ -33,5 +49,7 @@ class TokenViewSet(ModelViewSet):
if not tokens.exists(): if not tokens.exists():
raise Http404 raise Http404
token = tokens.first() token = tokens.first()
Event.new(EventAction.TOKEN_VIEW, token=token).from_http(request) Event.new(EventAction.SECRET_VIEW, secret=token).from_http( # noqa # nosec
return Response({"key": token.key}) request
)
return Response(TokenViewSerializer({"key": token.key}).data)

View File

@ -2,15 +2,29 @@
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509 import load_pem_x509_certificate from cryptography.x509 import load_pem_x509_certificate
from rest_framework.serializers import ModelSerializer, ValidationError from django.db.models import Model
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.fields import CharField, DateTimeField, SerializerMethodField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, Serializer, ValidationError
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.events.models import Event, EventAction
class CertificateKeyPairSerializer(ModelSerializer): class CertificateKeyPairSerializer(ModelSerializer):
"""CertificateKeyPair Serializer""" """CertificateKeyPair Serializer"""
cert_expiry = DateTimeField(source="certificate.not_valid_after", read_only=True)
cert_subject = SerializerMethodField()
def get_cert_subject(self, instance: CertificateKeyPair) -> str:
"""Get certificate subject as full rfc4514"""
return instance.certificate.subject.rfc4514_string()
def validate_certificate_data(self, value): def validate_certificate_data(self, value):
"""Verify that input is a valid PEM x509 Certificate""" """Verify that input is a valid PEM x509 Certificate"""
try: try:
@ -36,7 +50,31 @@ class CertificateKeyPairSerializer(ModelSerializer):
class Meta: class Meta:
model = CertificateKeyPair model = CertificateKeyPair
fields = ["pk", "name", "certificate_data", "key_data"] fields = [
"pk",
"name",
"fingerprint",
"certificate_data",
"key_data",
"cert_expiry",
"cert_subject",
]
extra_kwargs = {
"key_data": {"write_only": True},
"certificate_data": {"write_only": True},
}
class CertificateDataSerializer(Serializer):
"""Get CertificateKeyPair's data"""
data = CharField(read_only=True)
def create(self, validated_data: dict) -> Model:
raise NotImplementedError
def update(self, instance: Model, validated_data: dict) -> Model:
raise NotImplementedError
class CertificateKeyPairViewSet(ModelViewSet): class CertificateKeyPairViewSet(ModelViewSet):
@ -44,3 +82,31 @@ class CertificateKeyPairViewSet(ModelViewSet):
queryset = CertificateKeyPair.objects.all() queryset = CertificateKeyPair.objects.all()
serializer_class = CertificateKeyPairSerializer serializer_class = CertificateKeyPairSerializer
@swagger_auto_schema(responses={200: CertificateDataSerializer(many=False)})
@action(detail=True)
# pylint: disable=invalid-name, unused-argument
def view_certificate(self, request: Request, pk: str) -> Response:
"""Return certificate-key pairs certificate and log access"""
certificate: CertificateKeyPair = self.get_object()
Event.new( # noqa # nosec
EventAction.SECRET_VIEW,
secret=certificate,
type="certificate",
).from_http(request)
return Response(
CertificateDataSerializer({"data": certificate.certificate_data}).data
)
@swagger_auto_schema(responses={200: CertificateDataSerializer(many=False)})
@action(detail=True)
# pylint: disable=invalid-name, unused-argument
def view_private_key(self, request: Request, pk: str) -> Response:
"""Return certificate-key pairs private key and log access"""
certificate: CertificateKeyPair = self.get_object()
Event.new( # noqa # nosec
EventAction.SECRET_VIEW,
secret=certificate,
type="private_key",
).from_http(request)
return Response(CertificateDataSerializer({"data": certificate.key_data}).data)

View File

@ -0,0 +1,61 @@
# Generated by Django 3.1.6 on 2021-02-09 16:57
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def token_view_to_secret_view(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.events.models import EventAction
db_alias = schema_editor.connection.alias
Event = apps.get_model("authentik_events", "Event")
events = Event.objects.using(db_alias).filter(action="token_view")
for event in events:
event.context["secret"] = event.context.pop("token")
event.action = EventAction.SECRET_VIEW
Event.objects.using(db_alias).bulk_update(events, ["context", "action"])
class Migration(migrations.Migration):
dependencies = [
("authentik_events", "0012_auto_20210202_1821"),
]
operations = [
migrations.AlterField(
model_name="event",
name="action",
field=models.TextField(
choices=[
("login", "Login"),
("login_failed", "Login Failed"),
("logout", "Logout"),
("user_write", "User Write"),
("suspicious_request", "Suspicious Request"),
("password_set", "Password Set"),
("secret_view", "Secret View"),
("invitation_used", "Invite Used"),
("authorize_application", "Authorize Application"),
("source_linked", "Source Linked"),
("impersonation_started", "Impersonation Started"),
("impersonation_ended", "Impersonation Ended"),
("policy_execution", "Policy Execution"),
("policy_exception", "Policy Exception"),
("property_mapping_exception", "Property Mapping Exception"),
("system_task_execution", "System Task Execution"),
("system_task_exception", "System Task Exception"),
("configuration_error", "Configuration Error"),
("model_created", "Model Created"),
("model_updated", "Model Updated"),
("model_deleted", "Model Deleted"),
("update_available", "Update Available"),
("custom_", "Custom Prefix"),
]
),
),
migrations.RunPython(token_view_to_secret_view),
]

View File

@ -42,7 +42,7 @@ class EventAction(models.TextChoices):
SUSPICIOUS_REQUEST = "suspicious_request" SUSPICIOUS_REQUEST = "suspicious_request"
PASSWORD_SET = "password_set" # noqa # nosec PASSWORD_SET = "password_set" # noqa # nosec
TOKEN_VIEW = "token_view" # nosec SECRET_VIEW = "secret_view" # noqa # nosec
INVITE_USED = "invitation_used" INVITE_USED = "invitation_used"

View File

@ -98,6 +98,10 @@ class BaseEvaluator:
exec(ast_obj, self._globals, _locals) # nosec # noqa exec(ast_obj, self._globals, _locals) # nosec # noqa
result = _locals["result"] result = _locals["result"]
except Exception as exc: except Exception as exc:
# So, this is a bit questionable. Essentially, we are edit the stacktrace
# so the user only sees information relevant to them
# and none of our surrounding error handling
exc.__traceback__ = exc.__traceback__.tb_next
self.handle_error(exc, expression_source) self.handle_error(exc, expression_source)
raise exc raise exc
return result return result

View File

@ -1,30 +1,28 @@
"""Outpost API Views""" """Outpost API Views"""
from rest_framework.serializers import JSONField, ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.outposts.models import ( from authentik.outposts.models import (
DockerServiceConnection, DockerServiceConnection,
KubernetesServiceConnection, KubernetesServiceConnection,
Outpost, OutpostServiceConnection,
) )
class OutpostSerializer(ModelSerializer): class ServiceConnectionSerializer(ModelSerializer):
"""Outpost Serializer""" """ServiceConnection Serializer"""
_config = JSONField()
class Meta: class Meta:
model = Outpost model = OutpostServiceConnection
fields = ["pk", "name", "providers", "service_connection", "_config"] fields = ["pk", "name"]
class OutpostViewSet(ModelViewSet): class ServiceConnectionViewSet(ModelViewSet):
"""Outpost Viewset""" """ServiceConnection Viewset"""
queryset = Outpost.objects.all() queryset = OutpostServiceConnection.objects.all()
serializer_class = OutpostSerializer serializer_class = ServiceConnectionSerializer
class DockerServiceConnectionSerializer(ModelSerializer): class DockerServiceConnectionSerializer(ModelSerializer):

View File

@ -0,0 +1,79 @@
"""Outpost API Views"""
from django.db.models import Model
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.fields import BooleanField, CharField, DateTimeField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import JSONField, ModelSerializer, Serializer
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
from authentik.outposts.models import Outpost
class OutpostSerializer(ModelSerializer):
"""Outpost Serializer"""
_config = JSONField()
providers_obj = ProviderSerializer(source="providers", many=True, read_only=True)
class Meta:
model = Outpost
fields = [
"pk",
"name",
"providers",
"providers_obj",
"service_connection",
"token_identifier",
"_config",
]
class OutpostHealthSerializer(Serializer):
"""Outpost health status"""
last_seen = DateTimeField(read_only=True)
version = CharField(read_only=True)
version_should = CharField(read_only=True)
version_outdated = BooleanField(read_only=True)
def create(self, validated_data: dict) -> Model:
raise NotImplementedError
def update(self, instance: Model, validated_data: dict) -> Model:
raise NotImplementedError
class OutpostViewSet(ModelViewSet):
"""Outpost Viewset"""
queryset = Outpost.objects.all()
serializer_class = OutpostSerializer
filterset_fields = {
"providers": ["isnull"],
}
search_fields = [
"name",
"providers__name",
]
@swagger_auto_schema(responses={200: OutpostHealthSerializer(many=True)})
@action(methods=["GET"], detail=True)
# pylint: disable=invalid-name, unused-argument
def health(self, request: Request, pk: int) -> Response:
"""Get outposts current health"""
outpost: Outpost = self.get_object()
states = []
for state in outpost.state:
states.append(
{
"last_seen": state.last_seen,
"version": state.version,
"version_should": state.version_should,
"version_outdated": state.version_outdated,
}
)
return Response(OutpostHealthSerializer(states, many=True).data)

View File

@ -9,7 +9,6 @@ from django.core.cache import cache
from django.db import models, transaction from django.db import models, transaction
from django.db.models.base import Model from django.db.models.base import Model
from django.forms.models import ModelForm from django.forms.models import ModelForm
from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from docker.client import DockerClient from docker.client import DockerClient
from docker.errors import DockerException from docker.errors import DockerException
@ -33,7 +32,6 @@ from authentik.crypto.models import CertificateKeyPair
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.lib.models import InheritanceForeignKey from authentik.lib.models import InheritanceForeignKey
from authentik.lib.sentry import SentryIgnoredException from authentik.lib.sentry import SentryIgnoredException
from authentik.lib.utils.template import render_to_string
from authentik.outposts.docker_tls import DockerInlineTLS from authentik.outposts.docker_tls import DockerInlineTLS
OUR_VERSION = parse(__version__) OUR_VERSION = parse(__version__)
@ -378,13 +376,6 @@ class Outpost(models.Model):
objects.append(provider) objects.append(provider)
return objects return objects
def html_deployment_view(self, request: HttpRequest) -> Optional[str]:
"""return template and context modal to view token and other config info"""
return render_to_string(
"outposts/deployment_modal.html",
{"outpost": self, "full_url": request.build_absolute_uri("/")},
)
def __str__(self) -> str: def __str__(self) -> str:
return f"Outpost {self.name}" return f"Outpost {self.name}"

View File

@ -20,6 +20,7 @@ UPDATE_TRIGGERING_MODELS = (
@receiver(post_save) @receiver(post_save)
# pylint: disable=unused-argument
def post_save_update(sender, instance: Model, **_): def post_save_update(sender, instance: Model, **_):
"""If an Outpost is saved, Ensure that token is created/updated """If an Outpost is saved, Ensure that token is created/updated
@ -29,7 +30,7 @@ def post_save_update(sender, instance: Model, **_):
return return
if instance.__module__ == "__fake__": if instance.__module__ == "__fake__":
return return
if sender not in UPDATE_TRIGGERING_MODELS: if not isinstance(instance, UPDATE_TRIGGERING_MODELS):
return return
outpost_post_save.delay(class_to_path(instance.__class__), instance.pk) outpost_post_save.delay(class_to_path(instance.__class__), instance.pk)

View File

@ -1,43 +0,0 @@
{% load i18n %}
<ak-modal-button>
<button slot="trigger" class="pf-c-button pf-m-tertiary">
{% trans 'View Deployment Info' %}
</button>
<div slot="modal">
<div class="pf-c-modal-box__header">
<h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Outpost Deployment Info' %}</h1>
</div>
<div class="pf-c-modal-box__body" id="modal-description">
<p><a href="https://goauthentik.io/docs/outposts/outposts/#deploy">{% trans 'View deployment documentation' %}</a></p>
<form class="pf-c-form">
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_HOST</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="{{ full_url }}" />
</div>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_TOKEN</span>
</label>
<div>
<ak-token-copy-button identifier="{{ outpost.token_identifier }}">
{% trans 'Click to copy token' %}
</ak-token-copy-button>
</div>
</div>
<h3>{% trans 'If your authentik Instance is using a self-signed certificate, set this value.' %}</h3>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_INSECURE</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="true" />
</div>
</form>
</div>
<footer class="pf-c-modal-box__footer pf-m-align-left">
<a class="pf-c-button pf-m-primary">{% trans 'Close' %}</a>
</footer>
</div>
</ak-modal-button>

View File

@ -0,0 +1,46 @@
# Generated by Django 3.1.6 on 2021-02-09 16:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_policies_event_matcher", "0006_auto_20210203_1134"),
]
operations = [
migrations.AlterField(
model_name="eventmatcherpolicy",
name="action",
field=models.TextField(
blank=True,
choices=[
("login", "Login"),
("login_failed", "Login Failed"),
("logout", "Logout"),
("user_write", "User Write"),
("suspicious_request", "Suspicious Request"),
("password_set", "Password Set"),
("secret_view", "Secret View"),
("invitation_used", "Invite Used"),
("authorize_application", "Authorize Application"),
("source_linked", "Source Linked"),
("impersonation_started", "Impersonation Started"),
("impersonation_ended", "Impersonation Ended"),
("policy_execution", "Policy Execution"),
("policy_exception", "Policy Exception"),
("property_mapping_exception", "Property Mapping Exception"),
("system_task_execution", "System Task Execution"),
("system_task_exception", "System Task Exception"),
("configuration_error", "Configuration Error"),
("model_created", "Model Created"),
("model_updated", "Model Updated"),
("model_deleted", "Model Deleted"),
("update_available", "Update Available"),
("custom_", "Custom Prefix"),
],
help_text="Match created events with this action type. When left empty, all action types will be matched.",
),
),
]

View File

@ -55,10 +55,6 @@ class PolicyEvaluator(BaseEvaluator):
def handle_error(self, exc: Exception, expression_source: str): def handle_error(self, exc: Exception, expression_source: str):
"""Exception Handler""" """Exception Handler"""
# So, this is a bit questionable. Essentially, we are edit the stacktrace
# so the user only sees information relevant to them
# and none of our surrounding error handling
exc.__traceback__ = exc.__traceback__.tb_next
raise PolicyException(exc) raise PolicyException(exc)
def evaluate(self, expression_source: str) -> PolicyResult: def evaluate(self, expression_source: str) -> PolicyResult:

View File

@ -103,6 +103,7 @@ class PolicyProcess(PROCESS_CLASS):
# Invert result if policy.negate is set # Invert result if policy.negate is set
if self.binding.negate: if self.binding.negate:
policy_result.passing = not policy_result.passing policy_result.passing = not policy_result.passing
if not self.request.debug:
key = cache_key(self.binding, self.request) key = cache_key(self.binding, self.request)
cache.set(key, policy_result) cache.set(key, policy_result)
LOGGER.debug( LOGGER.debug(

View File

@ -59,11 +59,11 @@ class OAuth2ProviderViewSet(ModelViewSet):
queryset = OAuth2Provider.objects.all() queryset = OAuth2Provider.objects.all()
serializer_class = OAuth2ProviderSerializer serializer_class = OAuth2ProviderSerializer
@action(methods=["GET"], detail=True)
@swagger_auto_schema(responses={200: OAuth2ProviderSetupURLs(many=False)}) @swagger_auto_schema(responses={200: OAuth2ProviderSetupURLs(many=False)})
@action(methods=["GET"], detail=True)
# pylint: disable=invalid-name # pylint: disable=invalid-name
def setup_urls(self, request: Request, pk: int) -> str: def setup_urls(self, request: Request, pk: int) -> str:
"""Return metadata as XML string""" """Get Providers setup URLs"""
provider = get_object_or_404(OAuth2Provider, pk=pk) provider = get_object_or_404(OAuth2Provider, pk=pk)
data = { data = {
"issuer": provider.get_issuer(request), "issuer": provider.get_issuer(request),

View File

@ -23,6 +23,8 @@ return {
"family_name": "", "family_name": "",
"preferred_username": user.username, "preferred_username": user.username,
"nickname": user.username, "nickname": user.username,
# groups is not part of the official userinfo schema, but is a quasi-standard
"groups": [group.name for group in user.ak_groups.all()],
} }
""" """

View File

@ -253,6 +253,7 @@ class OAuthFulfillmentStage(StageView):
EventAction.AUTHORIZE_APPLICATION, EventAction.AUTHORIZE_APPLICATION,
authorized_application=application, authorized_application=application,
flow=self.executor.plan.flow_pk, flow=self.executor.plan.flow_pk,
scopes=", ".join(self.params.scope),
).from_http(self.request) ).from_http(self.request)
return redirect(self.create_response_uri()) return redirect(self.create_response_uri())
except (ClientIdError, RedirectUriError) as error: except (ClientIdError, RedirectUriError) as error:

View File

@ -18,7 +18,7 @@ class ProxyProviderForm(forms.ModelForm):
) )
self.fields["certificate"].queryset = CertificateKeyPair.objects.filter( self.fields["certificate"].queryset = CertificateKeyPair.objects.filter(
key_data__isnull=False key_data__isnull=False
) ).exclude(key_data="")
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
actual_save = super().save(*args, **kwargs) actual_save = super().save(*args, **kwargs)

View File

@ -54,10 +54,10 @@ class SAMLProviderViewSet(ModelViewSet):
queryset = SAMLProvider.objects.all() queryset = SAMLProvider.objects.all()
serializer_class = SAMLProviderSerializer serializer_class = SAMLProviderSerializer
@action(methods=["GET"], detail=True)
@swagger_auto_schema(responses={200: SAMLMetadataSerializer(many=False)}) @swagger_auto_schema(responses={200: SAMLMetadataSerializer(many=False)})
@action(methods=["GET"], detail=True)
# pylint: disable=invalid-name # pylint: disable=invalid-name
def metadata(self, request: Request, pk: int) -> str: def metadata(self, request: Request, pk: int) -> Response:
"""Return metadata as XML string""" """Return metadata as XML string"""
provider = get_object_or_404(SAMLProvider, pk=pk) provider = get_object_or_404(SAMLProvider, pk=pk)
metadata = DescriptorDownloadView.get_metadata(request, provider) metadata = DescriptorDownloadView.get_metadata(request, provider)

View File

@ -90,7 +90,7 @@ class ASGILogger:
if message["type"] == "http.response.body" and not message.get( if message["type"] == "http.response.body" and not message.get(
"more_body", None "more_body", None
): ):
runtime = int((time() - self.start) * 10 ** 6) runtime = int((time() - self.start) * 1000)
self.log(runtime) self.log(runtime)
await send(message) await send(message)

View File

@ -1,18 +1,27 @@
"""Source API Views""" """Source API Views"""
from rest_framework.serializers import ModelSerializer from datetime import datetime
from django.core.cache import cache
from django.db.models.base import Model
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.fields import DateTimeField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, Serializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.admin.forms.source import SOURCE_SERIALIZER_FIELDS from authentik.core.api.sources import SourceSerializer
from authentik.core.api.utils import MetaNameSerializer from authentik.core.api.utils import MetaNameSerializer
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
class LDAPSourceSerializer(ModelSerializer, MetaNameSerializer): class LDAPSourceSerializer(SourceSerializer):
"""LDAP Source Serializer""" """LDAP Source Serializer"""
class Meta: class Meta:
model = LDAPSource model = LDAPSource
fields = SOURCE_SERIALIZER_FIELDS + [ fields = SourceSerializer.Meta.fields + [
"server_uri", "server_uri",
"bind_cn", "bind_cn",
"bind_password", "bind_password",
@ -34,6 +43,39 @@ class LDAPSourceSerializer(ModelSerializer, MetaNameSerializer):
extra_kwargs = {"bind_password": {"write_only": True}} extra_kwargs = {"bind_password": {"write_only": True}}
class LDAPSourceSyncStatusSerializer(Serializer):
"""LDAP Sync status"""
last_sync = DateTimeField(read_only=True)
def create(self, validated_data: dict) -> Model:
raise NotImplementedError
def update(self, instance: Model, validated_data: dict) -> Model:
raise NotImplementedError
class LDAPSourceViewSet(ModelViewSet):
"""LDAP Source Viewset"""
queryset = LDAPSource.objects.all()
serializer_class = LDAPSourceSerializer
lookup_field = "slug"
@swagger_auto_schema(responses={200: LDAPSourceSyncStatusSerializer(many=False)})
@action(methods=["GET"], detail=True)
# pylint: disable=unused-argument
def sync_status(self, request: Request, slug: str) -> Response:
"""Get source's sync status"""
source = self.get_object()
last_sync = cache.get(source.state_cache_prefix("last_sync"), None)
return Response(
LDAPSourceSyncStatusSerializer(
{"last_sync": datetime.fromtimestamp(last_sync)}
).data
)
class LDAPPropertyMappingSerializer(ModelSerializer, MetaNameSerializer): class LDAPPropertyMappingSerializer(ModelSerializer, MetaNameSerializer):
"""LDAP PropertyMapping Serializer""" """LDAP PropertyMapping Serializer"""
@ -49,13 +91,6 @@ class LDAPPropertyMappingSerializer(ModelSerializer, MetaNameSerializer):
] ]
class LDAPSourceViewSet(ModelViewSet):
"""LDAP Source Viewset"""
queryset = LDAPSource.objects.all()
serializer_class = LDAPSourceSerializer
class LDAPPropertyMappingViewSet(ModelViewSet): class LDAPPropertyMappingViewSet(ModelViewSet):
"""LDAP PropertyMapping Viewset""" """LDAP PropertyMapping Viewset"""

View File

@ -1,8 +1,6 @@
"""authentik LDAP Models""" """authentik LDAP Models"""
from datetime import datetime
from typing import Optional, Type from typing import Optional, Type
from django.core.cache import cache
from django.db import models from django.db import models
from django.forms import ModelForm from django.forms import ModelForm
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -11,7 +9,6 @@ from rest_framework.serializers import Serializer
from authentik.core.models import Group, PropertyMapping, Source from authentik.core.models import Group, PropertyMapping, Source
from authentik.lib.models import DomainlessURLValidator from authentik.lib.models import DomainlessURLValidator
from authentik.lib.utils.template import render_to_string
class LDAPSource(Source): class LDAPSource(Source):
@ -91,16 +88,6 @@ class LDAPSource(Source):
"""Key by which the ldap source status is saved""" """Key by which the ldap source status is saved"""
return f"source_ldap_{self.pk}_state_{suffix}" return f"source_ldap_{self.pk}_state_{suffix}"
@property
def ui_additional_info(self) -> str:
last_sync = cache.get(self.state_cache_prefix("last_sync"), None)
if last_sync:
last_sync = datetime.fromtimestamp(last_sync)
return render_to_string(
"ldap/source_list_status.html", {"source": self, "last_sync": last_sync}
)
_connection: Optional[Connection] = None _connection: Optional[Connection] = None
@property @property

View File

@ -4,6 +4,7 @@ from time import time
from django.core.cache import cache from django.core.cache import cache
from django.utils.text import slugify from django.utils.text import slugify
from ldap3.core.exceptions import LDAPException from ldap3.core.exceptions import LDAPException
from structlog.stdlib import get_logger
from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
@ -12,6 +13,8 @@ from authentik.sources.ldap.sync.groups import GroupLDAPSynchronizer
from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer
from authentik.sources.ldap.sync.users import UserLDAPSynchronizer from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
LOGGER = get_logger()
@CELERY_APP.task() @CELERY_APP.task()
def ldap_sync_all(): def ldap_sync_all():
@ -21,7 +24,7 @@ def ldap_sync_all():
@CELERY_APP.task(bind=True, base=MonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def ldap_sync(self: MonitoredTask, source_pk: int): def ldap_sync(self: MonitoredTask, source_pk: str):
"""Synchronization of an LDAP Source""" """Synchronization of an LDAP Source"""
try: try:
source: LDAPSource = LDAPSource.objects.get(pk=source_pk) source: LDAPSource = LDAPSource.objects.get(pk=source_pk)
@ -49,4 +52,5 @@ def ldap_sync(self: MonitoredTask, source_pk: int):
) )
) )
except LDAPException as exc: except LDAPException as exc:
LOGGER.debug(exc)
self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc)) self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc))

View File

@ -1,8 +0,0 @@
{% load humanize %}
{% load i18n %}
{% if last_sync %}
<i class="fas fa-check pf-m-success"></i> {% blocktrans with last_sync=last_sync|naturaltime %}Synced {{ last_sync }}.{% endblocktrans %}
{% else %}
<i class="fas fa-times pf-m-danger"></i> Not synced yet/Sync in Progress
{% endif %}

View File

@ -1,18 +1,30 @@
"""OAuth Source Serializer""" """OAuth Source Serializer"""
from rest_framework.serializers import ModelSerializer from django.urls.base import reverse_lazy
from rest_framework.fields import SerializerMethodField
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.admin.forms.source import SOURCE_SERIALIZER_FIELDS from authentik.core.api.sources import SourceSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.sources.oauth.models import OAuthSource from authentik.sources.oauth.models import OAuthSource
class OAuthSourceSerializer(ModelSerializer, MetaNameSerializer): class OAuthSourceSerializer(SourceSerializer):
"""OAuth Source Serializer""" """OAuth Source Serializer"""
callback_url = SerializerMethodField()
def get_callback_url(self, instance: OAuthSource) -> str:
"""Get OAuth Callback URL"""
relative_url = reverse_lazy(
"authentik_sources_oauth:oauth-client-callback",
kwargs={"source_slug": instance.slug},
)
if "request" not in self.context:
return relative_url
return self.context["request"].build_absolute_uri(relative_url)
class Meta: class Meta:
model = OAuthSource model = OAuthSource
fields = SOURCE_SERIALIZER_FIELDS + [ fields = SourceSerializer.Meta.fields + [
"provider_type", "provider_type",
"request_token_url", "request_token_url",
"authorization_url", "authorization_url",
@ -20,7 +32,9 @@ class OAuthSourceSerializer(ModelSerializer, MetaNameSerializer):
"profile_url", "profile_url",
"consumer_key", "consumer_key",
"consumer_secret", "consumer_secret",
"callback_url",
] ]
extra_kwargs = {"consumer_secret": {"write_only": True}}
class OAuthSourceViewSet(ModelViewSet): class OAuthSourceViewSet(ModelViewSet):
@ -28,3 +42,4 @@ class OAuthSourceViewSet(ModelViewSet):
queryset = OAuthSource.objects.all() queryset = OAuthSource.objects.all()
serializer_class = OAuthSourceSerializer serializer_class = OAuthSourceSerializer
lookup_field = "slug"

View File

@ -2,7 +2,6 @@
from django import forms from django import forms
from authentik.admin.forms.source import SOURCE_FORM_FIELDS
from authentik.flows.models import Flow, FlowDesignation from authentik.flows.models import Flow, FlowDesignation
from authentik.sources.oauth.models import OAuthSource from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.types.manager import MANAGER from authentik.sources.oauth.types.manager import MANAGER
@ -27,7 +26,12 @@ class OAuthSourceForm(forms.ModelForm):
class Meta: class Meta:
model = OAuthSource model = OAuthSource
fields = SOURCE_FORM_FIELDS + [ fields = [
"name",
"slug",
"enabled",
"authentication_flow",
"enrollment_flow",
"provider_type", "provider_type",
"request_token_url", "request_token_url",
"authorization_url", "authorization_url",

View File

@ -64,14 +64,6 @@ class OAuthSource(Source):
name=self.name, name=self.name,
) )
@property
def ui_additional_info(self) -> str:
url = reverse_lazy(
"authentik_sources_oauth:oauth-client-callback",
kwargs={"source_slug": self.slug},
)
return f"Callback URL: <pre>{url}</pre>"
@property @property
def ui_user_settings(self) -> Optional[str]: def ui_user_settings(self) -> Optional[str]:
view_name = "authentik_sources_oauth:oauth-client-user" view_name = "authentik_sources_oauth:oauth-client-user"

View File

@ -1,19 +1,17 @@
"""SAMLSource API Views""" """SAMLSource API Views"""
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.admin.forms.source import SOURCE_FORM_FIELDS from authentik.core.api.sources import SourceSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.sources.saml.models import SAMLSource from authentik.sources.saml.models import SAMLSource
class SAMLSourceSerializer(ModelSerializer, MetaNameSerializer): class SAMLSourceSerializer(SourceSerializer):
"""SAMLSource Serializer""" """SAMLSource Serializer"""
class Meta: class Meta:
model = SAMLSource model = SAMLSource
fields = SOURCE_FORM_FIELDS + [ fields = SourceSerializer.Meta.fields + [
"issuer", "issuer",
"sso_url", "sso_url",
"slo_url", "slo_url",
@ -32,3 +30,4 @@ class SAMLSourceViewSet(ModelViewSet):
queryset = SAMLSource.objects.all() queryset = SAMLSource.objects.all()
serializer_class = SAMLSourceSerializer serializer_class = SAMLSourceSerializer
lookup_field = "slug"

View File

@ -2,7 +2,6 @@
from django import forms from django import forms
from authentik.admin.forms.source import SOURCE_FORM_FIELDS
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.flows.models import Flow, FlowDesignation from authentik.flows.models import Flow, FlowDesignation
from authentik.sources.saml.models import SAMLSource from authentik.sources.saml.models import SAMLSource
@ -28,7 +27,12 @@ class SAMLSourceForm(forms.ModelForm):
class Meta: class Meta:
model = SAMLSource model = SAMLSource
fields = SOURCE_FORM_FIELDS + [ fields = [
"name",
"slug",
"enabled",
"authentication_flow",
"enrollment_flow",
"issuer", "issuer",
"sso_url", "sso_url",
"slo_url", "slo_url",

View File

@ -19,7 +19,7 @@ services:
networks: networks:
- internal - internal
server: server:
image: beryju/authentik:${AUTHENTIK_TAG:-2021.2.1-rc2} image: beryju/authentik:${AUTHENTIK_TAG:-2021.2.2-stable}
command: server command: server
environment: environment:
AUTHENTIK_REDIS__HOST: redis AUTHENTIK_REDIS__HOST: redis
@ -45,7 +45,7 @@ services:
env_file: env_file:
- .env - .env
worker: worker:
image: beryju/authentik:${AUTHENTIK_TAG:-2021.2.1-rc2} image: beryju/authentik:${AUTHENTIK_TAG:-2021.2.2-stable}
command: worker command: worker
networks: networks:
- internal - internal
@ -62,7 +62,7 @@ services:
env_file: env_file:
- .env - .env
static: static:
image: beryju/authentik-static:${AUTHENTIK_TAG:-2021.2.1-rc2} image: beryju/authentik-static:${AUTHENTIK_TAG:-2021.2.2-stable}
networks: networks:
- internal - internal
labels: labels:

View File

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

View File

@ -4,7 +4,7 @@
|-----------------------------------|-------------------------|-------------| |-----------------------------------|-------------------------|-------------|
| image.name | beryju/authentik | Image used to run the authentik server and worker | | 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.name_static | beryju/authentik-static | Image used to run the authentik static server (CSS and JS Files) |
| image.tag | 2021.2.1-rc2 | Image tag | | image.tag | 2021.2.2-stable | Image tag |
| image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments | | image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments |
| serverReplicas | 1 | Replicas for the Server deployment | | serverReplicas | 1 | Replicas for the Server deployment |
| workerReplicas | 1 | Replicas for the Worker deployment | | workerReplicas | 1 | Replicas for the Worker deployment |

View File

@ -5,7 +5,7 @@ image:
name: beryju/authentik name: beryju/authentik
name_static: beryju/authentik-static name_static: beryju/authentik-static
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
tag: 2021.2.1-rc2 tag: 2021.2.2-stable
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
serverReplicas: 1 serverReplicas: 1

View File

@ -3,40 +3,39 @@ module goauthentik.io/outpost
go 1.14 go 1.14
require ( require (
cloud.google.com/go v0.64.0 // indirect
github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc v2.2.1+incompatible
github.com/getsentry/sentry-go v0.9.0 github.com/getsentry/sentry-go v0.9.0
github.com/go-openapi/errors v0.19.9 github.com/go-openapi/errors v0.20.0
github.com/go-openapi/runtime v0.19.24 github.com/go-openapi/runtime v0.19.26
github.com/go-openapi/strfmt v0.19.12 github.com/go-openapi/strfmt v0.20.0
github.com/go-openapi/swag v0.19.12 github.com/go-openapi/swag v0.19.14
github.com/go-openapi/validate v0.20.1 github.com/go-openapi/validate v0.20.2
github.com/go-redis/redis/v7 v7.4.0 // indirect github.com/go-redis/redis/v7 v7.4.0 // indirect
github.com/go-swagger/go-swagger v0.25.0 // indirect github.com/go-swagger/go-swagger v0.26.1 // indirect
github.com/gorilla/handlers v1.5.1 // indirect github.com/golang/protobuf v1.4.3 // indirect
github.com/gorilla/websocket v1.4.2 github.com/gorilla/websocket v1.4.2
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/justinas/alice v1.2.0 github.com/justinas/alice v1.2.0
github.com/kr/pretty v0.2.1 // indirect github.com/kr/pretty v0.2.1 // indirect
github.com/magiconair/properties v1.8.4 // indirect github.com/magiconair/properties v1.8.4 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/oauth2-proxy/oauth2-proxy v0.0.0-20200831161845-e4e5580852dc github.com/oauth2-proxy/oauth2-proxy v0.0.0-20200831161845-e4e5580852dc
github.com/pelletier/go-toml v1.8.1 // indirect github.com/pelletier/go-toml v1.8.1 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f // indirect github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e // indirect
github.com/recws-org/recws v1.2.2 github.com/recws-org/recws v1.2.1
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.7.0
github.com/spf13/afero v1.5.1 // indirect github.com/spf13/afero v1.5.1 // indirect
github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.1 // indirect github.com/spf13/viper v1.7.1 // indirect
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 // indirect
golang.org/x/mod v0.4.1 // indirect golang.org/x/mod v0.4.1 // indirect
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 // indirect
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 // indirect golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
golang.org/x/text v0.3.5 // indirect golang.org/x/tools v0.1.0 // indirect
golang.org/x/tools v0.0.0-20210115202250-e0d201561e39 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect
) )

View File

@ -13,8 +13,8 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.64.0 h1:xVP3LPvMjGT4J0a55y02Gw5y/dkY/rxGz58sfK1jqIo= cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
cloud.google.com/go v0.64.0/go.mod h1:xfORb36jGvE+6EexW71nMEtL025s3x6xvuYUKM4JLv4= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@ -35,11 +35,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BeryJu/authentik v0.0.0-20210108085217-fd6d99f4f999 h1:ymxzvnxKNUomJIRG1VP3I6ls5mWn8r1xWD82bHASEk0=
github.com/BeryJu/authentik v0.0.0-20210116180903-8acb9dde5f2f h1:pLOJgn8bIzavtn0h874lys3gs7uk1RnMqMWIttOWY8Y=
github.com/BeryJu/authentik/proxy v0.0.0-20210108085217-fd6d99f4f999 h1:XYHeaZx7fm4JNx77MHMO6ek/Gdp+sZa2jIJyjC294Gw=
github.com/BeryJu/authentik/proxy v0.0.0-20210116180903-8acb9dde5f2f h1:bp617AbteaVcZBXMtr4/A+FSSVGKqRWlTo5chcirq8k=
github.com/BeryJu/authentik/proxy v0.0.0-20210116180903-8acb9dde5f2f/go.mod h1:6/VeRMuLHUE3Ywr1uIpjxnmOJJsAfld7OOOi+uocxQw=
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb h1:ZVN4Iat3runWOFLaBCDVU5a9X/XikSRBosye++6gojw= github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb h1:ZVN4Iat3runWOFLaBCDVU5a9X/XikSRBosye++6gojw=
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb/go.mod h1:WsAABbY4HQBgd3mGuG4KMNTbHJCPvx9IVBHzysbknss= github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb/go.mod h1:WsAABbY4HQBgd3mGuG4KMNTbHJCPvx9IVBHzysbknss=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
@ -167,6 +162,8 @@ github.com/go-openapi/analysis v0.19.10 h1:5BHISBAXOc/aJK25irLZnx2D3s6WyYaY9D4gm
github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ=
github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY= github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY=
github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= 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/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
@ -179,6 +176,8 @@ github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAw
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= 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 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= 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.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
@ -193,7 +192,6 @@ github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
@ -209,14 +207,18 @@ github.com/go-openapi/loads v0.19.7 h1:6cALLpCAq4tYhaic7TMbEzjv8vq/wg+0AFivNy/Bm
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
github.com/go-openapi/loads v0.20.0 h1:Pymw1O8zDmWeNv4kVsHd0W3cvgdp8juRa4U/U/8D/Pk= github.com/go-openapi/loads v0.20.0 h1:Pymw1O8zDmWeNv4kVsHd0W3cvgdp8juRa4U/U/8D/Pk=
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
github.com/go-openapi/loads v0.20.1/go.mod h1:/6LfFL8fDvTSX8ypmYXIq3U9Q7nfniSOStW22m864WM=
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= 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.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
github.com/go-openapi/runtime v0.19.20/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4=
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0=
github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= 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.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
@ -228,6 +230,10 @@ github.com/go-openapi/spec v0.19.15 h1:uxh8miNJEfMm8l8ekpY7i39LcORm1xSRtoipEGl1J
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I= github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I=
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
@ -238,8 +244,8 @@ github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9w
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/strfmt v0.19.11 h1:0+YvbNh05rmBkgztd6zHp4OCFn7Mtu30bn46NQo2ZRw= github.com/go-openapi/strfmt v0.19.11 h1:0+YvbNh05rmBkgztd6zHp4OCFn7Mtu30bn46NQo2ZRw=
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.19.12 h1:GcJYVoo6b2fsAzIxHTL6bTIcGo7vCJTfty+mdyj5VXo= github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM=
github.com/go-openapi/strfmt v0.19.12/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
@ -249,6 +255,10 @@ github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4az
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI=
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
github.com/go-openapi/swag v0.19.13 h1:233UVgMy1DlmCYYfOiFpta6e2urloh+sEs5id6lyzog=
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
@ -258,10 +268,10 @@ github.com/go-openapi/validate v0.19.12 h1:mPLM/bfbd00PGOCJlU0yJL7IulkZ+q9VjPv7U
github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4=
github.com/go-openapi/validate v0.19.15 h1:oUHZO8jD7p5oRLANlXF0U8ic9ePBUkDQyRZdN0EhL6M= github.com/go-openapi/validate v0.19.15 h1:oUHZO8jD7p5oRLANlXF0U8ic9ePBUkDQyRZdN0EhL6M=
github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI=
github.com/go-openapi/validate v0.20.0 h1:pzutNCCBZGZlE+u8HD3JZyWdc/TVbtVwlWUp8/vgUKk=
github.com/go-openapi/validate v0.20.0/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0=
github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s= github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s=
github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0=
github.com/go-openapi/validate v0.20.2 h1:AhqDegYV3J3iQkMPJSXkvzymHKMTw0BST3RK3hTT4ts=
github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0=
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs= github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
@ -269,8 +279,8 @@ 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-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 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-swagger/go-swagger v0.25.0 h1:FxhyrWWV8V/A9P6GtI5szWordAdbb6Y0nqdY/y9So2w= github.com/go-swagger/go-swagger v0.26.1 h1:1XUWLnH6hKxHzeKjJfA2gHkSqcT1Zgi4q/PZp2hDdN8=
github.com/go-swagger/go-swagger v0.25.0/go.mod h1:9639ioXrPX9E6BbnbaDklGXjNz7upAXoNBwL4Ok11Vk= github.com/go-swagger/go-swagger v0.26.1/go.mod h1:zlf/LHplZpdtU2mYXg9Ajd3+9TgHYltv5f/pEM6LjnI=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= 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/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.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
@ -331,6 +341,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 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/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3 h1:6amM4HsNPOvMLVc2ZnyqrjeQ92YAVWn7T4WBKK87inY= github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3 h1:6amM4HsNPOvMLVc2ZnyqrjeQ92YAVWn7T4WBKK87inY=
github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
@ -371,8 +383,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/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 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= 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/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.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@ -415,7 +425,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/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/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/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= 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/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
@ -483,6 +492,8 @@ github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
@ -544,13 +555,14 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= 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.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI=
@ -568,8 +580,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f h1:JDEmUDtyiLMyMlFwiaDOv2hxUp35497fkwePcLeV7j4= github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e h1:BLqxdwZ6j771IpSCRx7s/GJjXHUE00Hmu7/YegCGdzA=
github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ= github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -580,8 +592,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/recws-org/recws v1.2.2 h1:TkyyCEgMjsr1D2fnutY/DPhGnUKCLpJeXDAGy6rLmGE= github.com/recws-org/recws v1.2.1 h1:bYocRkAsS71hlQ9AMCVS+hYXHEgEyQsAbYKXf394gZ8=
github.com/recws-org/recws v1.2.2/go.mod h1:SxTgwQU/jqYSzEgUh4ifDxq/7enApS150f8nZ5Sczk8= github.com/recws-org/recws v1.2.1/go.mod h1:SxTgwQU/jqYSzEgUh4ifDxq/7enApS150f8nZ5Sczk8=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -608,8 +620,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ=
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg=
github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
@ -630,7 +640,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs= github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs=
github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= 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 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -643,6 +652,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
@ -691,11 +702,13 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE=
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW6TgOeJ5c=
go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8=
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs=
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.5/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@ -706,7 +719,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
goauthentik.io/outpost v0.0.0-20210108085217-fd6d99f4f999 h1:XYHeaZx7fm4JNx77MHMO6ek/Gdp+sZa2jIJyjC294Gw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -724,9 +736,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -759,8 +770,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -806,14 +815,15 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@ -821,6 +831,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -881,18 +893,14 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818 h1:f1CIuDlJhwANEC2MM87MBEVMr3jl5bifgsfj90XAF9c=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
golang.org/x/sys v0.0.0-20210108172913-0df2131ae363 h1:wHn06sgWHMO1VsQ8F+KzDJx/JzqfsNLnc+oEi07qD7s= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210108172913-0df2131ae363/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-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -959,17 +967,13 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 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-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200817023811-d00afeaade8f h1:33yHANSyO/TeglgY9rBhUpX43wtonTXoFOsMRtNB6qE= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200817023811-d00afeaade8f/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b h1:Lq5JUTFhiybGVf28jB6QRpqd13/JPOaCnET17PVzYJE=
golang.org/x/tools v0.0.0-20201226215659-b1c90890d22a h1:pdfjQ7VswBeGam3EpuEJ4e8EAb7JgaubV570LO/SIQM= golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201226215659-b1c90890d22a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e h1:Z2uDrs8MyXUWJbwGc4V+nGjV4Ygo+oubBbWSVQw21/I= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210115202250-e0d201561e39 h1:BTs2GMGSMWpgtCpv1CE7vkJTv7XcHdcLLnAMu7UbgTY=
golang.org/x/tools v0.0.0-20210115202250-e0d201561e39/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1004,6 +1008,8 @@ google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpC
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -1033,8 +1039,8 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 h1:wboULUXGF3c5qdUnKp+6gLAccE6PRpa/czkYvQ4UXv8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8=
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1078,7 +1084,6 @@ gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/R
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
@ -1108,6 +1113,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -69,23 +69,10 @@ func (ac *APIController) Shutdown() {
} }
func (ac *APIController) startWSHandler() { func (ac *APIController) startWSHandler() {
notConnectedBackoff := 1
logger := ac.logger.WithField("loop", "ws-handler") logger := ac.logger.WithField("loop", "ws-handler")
for { for {
if !ac.wsConn.IsConnected() { if !ac.wsConn.IsConnected() {
notConnectedWait := time.Duration(notConnectedBackoff) * time.Second
logger.WithField("wait", notConnectedWait).Info("Not connected, trying again...")
time.Sleep(notConnectedWait)
notConnectedBackoff += notConnectedBackoff
// Limit backoff to max 60 seconds
if notConnectedBackoff >= 60 {
notConnectedBackoff = 60
}
ac.wsConn.CloseAndReconnect()
continue continue
} else {
// When we're connected, reset backoff to 1
notConnectedBackoff = 1
} }
var wsMsg websocketMessage var wsMsg websocketMessage
err := ac.wsConn.ReadJSON(&wsMsg) err := ac.wsConn.ReadJSON(&wsMsg)

View File

@ -68,7 +68,7 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
if provider.Certificate != nil { if provider.Certificate != nil {
pb.log.WithField("provider", provider.ClientID).Debug("Enabling TLS") pb.log.WithField("provider", provider.ClientID).Debug("Enabling TLS")
cert, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsRead(&crypto.CryptoCertificatekeypairsReadParams{ cert, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewCertificate(&crypto.CryptoCertificatekeypairsViewCertificateParams{
Context: context.Background(), Context: context.Background(),
KpUUID: *provider.Certificate, KpUUID: *provider.Certificate,
}, pb.s.ak.Auth) }, pb.s.ak.Auth)
@ -76,13 +76,22 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to fetch certificate") pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to fetch certificate")
return providerOpts return providerOpts
} }
x509cert, err := tls.X509KeyPair([]byte(*cert.Payload.CertificateData), []byte(cert.Payload.KeyData)) key, err := pb.s.ak.Client.Crypto.CryptoCertificatekeypairsViewPrivateKey(&crypto.CryptoCertificatekeypairsViewPrivateKeyParams{
Context: context.Background(),
KpUUID: *provider.Certificate,
}, pb.s.ak.Auth)
if err != nil {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to fetch private key")
return providerOpts
}
x509cert, err := tls.X509KeyPair([]byte(*&cert.Payload.Data), []byte(key.Payload.Data))
if err != nil { if err != nil {
pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to parse certificate") pb.log.WithField("provider", provider.ClientID).WithError(err).Warning("Failed to parse certificate")
return providerOpts return providerOpts
} }
pb.cert = &x509cert pb.cert = &x509cert
pb.log.WithField("provider", provider.ClientID).WithField("certificate-key-pair", *cert.Payload.Name).Debug("Loaded certificates") pb.log.WithField("provider", provider.ClientID).Debug("Loaded certificates")
} }
return providerOpts return providerOpts
} }

View File

@ -1,3 +1,3 @@
package pkg package pkg
const VERSION = "2021.2.1-rc2" const VERSION = "2021.2.2-stable"

View File

@ -565,9 +565,9 @@ paths:
parameters: [] parameters: []
responses: responses:
'200': '200':
description: '' description: Show token's current key
schema: schema:
$ref: '#/definitions/Token' $ref: '#/definitions/TokenView'
tags: tags:
- core - core
parameters: parameters:
@ -863,6 +863,44 @@ paths:
required: true required: true
type: string type: string
format: uuid format: uuid
/crypto/certificatekeypairs/{kp_uuid}/view_certificate/:
get:
operationId: crypto_certificatekeypairs_view_certificate
description: Return certificate-key pairs certificate and log access
parameters: []
responses:
'200':
description: Get CertificateKeyPair's data
schema:
$ref: '#/definitions/CertificateData'
tags:
- crypto
parameters:
- name: kp_uuid
in: path
description: A UUID string identifying this Certificate-Key Pair.
required: true
type: string
format: uuid
/crypto/certificatekeypairs/{kp_uuid}/view_private_key/:
get:
operationId: crypto_certificatekeypairs_view_private_key
description: Return certificate-key pairs private key and log access
parameters: []
responses:
'200':
description: Get CertificateKeyPair's data
schema:
$ref: '#/definitions/CertificateData'
tags:
- crypto
parameters:
- name: kp_uuid
in: path
description: A UUID string identifying this Certificate-Key Pair.
required: true
type: string
format: uuid
/events/events/: /events/events/:
get: get:
operationId: events_events_list operationId: events_events_list
@ -1789,6 +1827,11 @@ paths:
operationId: outposts_outposts_list operationId: outposts_outposts_list
description: Outpost Viewset description: Outpost Viewset
parameters: parameters:
- name: providers__isnull
in: query
description: ''
required: false
type: string
- name: ordering - name: ordering
in: query in: query
description: Which field to use when ordering the results. description: Which field to use when ordering the results.
@ -1911,6 +1954,28 @@ paths:
required: true required: true
type: string type: string
format: uuid format: uuid
/outposts/outposts/{uuid}/health/:
get:
operationId: outposts_outposts_health
description: Get outposts current health
parameters: []
responses:
'200':
description: Outpost health status
schema:
description: ''
type: array
items:
$ref: '#/definitions/OutpostHealth'
tags:
- outposts
parameters:
- name: uuid
in: path
description: A UUID string identifying this outpost.
required: true
type: string
format: uuid
/outposts/proxy/: /outposts/proxy/:
get: get:
operationId: outposts_proxy_list operationId: outposts_proxy_list
@ -2037,6 +2102,133 @@ paths:
description: A unique integer value identifying this Proxy Provider. description: A unique integer value identifying this Proxy Provider.
required: true required: true
type: integer type: integer
/outposts/service_connections/all/:
get:
operationId: outposts_service_connections_all_list
description: ServiceConnection Viewset
parameters:
- 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: A page number within the paginated result set.
required: false
type: integer
- name: page_size
in: query
description: Number of results to return per page.
required: false
type: integer
responses:
'200':
description: ''
schema:
required:
- count
- results
type: object
properties:
count:
type: integer
next:
type: string
format: uri
x-nullable: true
previous:
type: string
format: uri
x-nullable: true
results:
type: array
items:
$ref: '#/definitions/ServiceConnection'
tags:
- outposts
post:
operationId: outposts_service_connections_all_create
description: ServiceConnection Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/ServiceConnection'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/ServiceConnection'
tags:
- outposts
parameters: []
/outposts/service_connections/all/{uuid}/:
get:
operationId: outposts_service_connections_all_read
description: ServiceConnection Viewset
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/ServiceConnection'
tags:
- outposts
put:
operationId: outposts_service_connections_all_update
description: ServiceConnection Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/ServiceConnection'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/ServiceConnection'
tags:
- outposts
patch:
operationId: outposts_service_connections_all_partial_update
description: ServiceConnection Viewset
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/ServiceConnection'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/ServiceConnection'
tags:
- outposts
delete:
operationId: outposts_service_connections_all_delete
description: ServiceConnection Viewset
parameters: []
responses:
'204':
description: ''
tags:
- outposts
parameters:
- name: uuid
in: path
description: A UUID string identifying this Outpost Service-Connection.
required: true
type: string
format: uuid
/outposts/service_connections/docker/: /outposts/service_connections/docker/:
get: get:
operationId: outposts_service_connections_docker_list operationId: outposts_service_connections_docker_list
@ -4308,7 +4500,7 @@ paths:
/providers/oauth2/{id}/setup_urls/: /providers/oauth2/{id}/setup_urls/:
get: get:
operationId: providers_oauth2_setup_urls operationId: providers_oauth2_setup_urls
description: Return metadata as XML string description: Get Providers setup URLs
parameters: [] parameters: []
responses: responses:
'200': '200':
@ -4763,7 +4955,7 @@ paths:
tags: tags:
- sources - sources
parameters: [] parameters: []
/sources/ldap/{pbm_uuid}/: /sources/ldap/{slug}/:
get: get:
operationId: sources_ldap_read operationId: sources_ldap_read
description: LDAP Source Viewset description: LDAP Source Viewset
@ -4817,12 +5009,33 @@ paths:
tags: tags:
- sources - sources
parameters: parameters:
- name: pbm_uuid - name: slug
in: path in: path
description: A UUID string identifying this LDAP Source. description: Internal source name, used in URLs.
required: true required: true
type: string type: string
format: uuid format: slug
pattern: ^[-a-zA-Z0-9_]+$
/sources/ldap/{slug}/sync_status/:
get:
operationId: sources_ldap_sync_status
description: Get source's sync status
parameters: []
responses:
'200':
description: LDAP Sync status
schema:
$ref: '#/definitions/LDAPSourceSyncStatus'
tags:
- sources
parameters:
- name: slug
in: path
description: Internal source name, used in URLs.
required: true
type: string
format: slug
pattern: ^[-a-zA-Z0-9_]+$
/sources/oauth/: /sources/oauth/:
get: get:
operationId: sources_oauth_list operationId: sources_oauth_list
@ -4890,7 +5103,7 @@ paths:
tags: tags:
- sources - sources
parameters: [] parameters: []
/sources/oauth/{pbm_uuid}/: /sources/oauth/{slug}/:
get: get:
operationId: sources_oauth_read operationId: sources_oauth_read
description: Source Viewset description: Source Viewset
@ -4944,12 +5157,13 @@ paths:
tags: tags:
- sources - sources
parameters: parameters:
- name: pbm_uuid - name: slug
in: path in: path
description: A UUID string identifying this Generic OAuth Source. description: Internal source name, used in URLs.
required: true required: true
type: string type: string
format: uuid format: slug
pattern: ^[-a-zA-Z0-9_]+$
/sources/saml/: /sources/saml/:
get: get:
operationId: sources_saml_list operationId: sources_saml_list
@ -5017,7 +5231,7 @@ paths:
tags: tags:
- sources - sources
parameters: [] parameters: []
/sources/saml/{pbm_uuid}/: /sources/saml/{slug}/:
get: get:
operationId: sources_saml_read operationId: sources_saml_read
description: SAMLSource Viewset description: SAMLSource Viewset
@ -5071,12 +5285,13 @@ paths:
tags: tags:
- sources - sources
parameters: parameters:
- name: pbm_uuid - name: slug
in: path in: path
description: A UUID string identifying this SAML Source. description: Internal source name, used in URLs.
required: true required: true
type: string type: string
format: uuid format: slug
pattern: ^[-a-zA-Z0-9_]+$
/stages/all/: /stages/all/:
get: get:
operationId: stages_all_list operationId: stages_all_list
@ -7536,6 +7751,15 @@ definitions:
description: description:
title: Description title: Description
type: string type: string
TokenView:
description: Show token's current key
type: object
properties:
key:
title: Key
type: string
readOnly: true
minLength: 1
User: User:
description: User Serializer description: User Serializer
required: required:
@ -7589,6 +7813,10 @@ definitions:
title: Name title: Name
type: string type: string
minLength: 1 minLength: 1
fingerprint:
title: Fingerprint
type: string
readOnly: true
certificate_data: certificate_data:
title: Certificate data title: Certificate data
description: PEM-encoded Certificate data description: PEM-encoded Certificate data
@ -7599,6 +7827,24 @@ definitions:
description: Optional Private Key. If this is set, you can use this keypair description: Optional Private Key. If this is set, you can use this keypair
for encryption. for encryption.
type: string type: string
cert_expiry:
title: Cert expiry
type: string
format: date-time
readOnly: true
cert_subject:
title: Cert subject
type: string
readOnly: true
CertificateData:
description: Get CertificateKeyPair's data
type: object
properties:
data:
title: Data
type: string
readOnly: true
minLength: 1
Event: Event:
description: Event Serializer description: Event Serializer
required: required:
@ -7624,7 +7870,7 @@ definitions:
- user_write - user_write
- suspicious_request - suspicious_request
- password_set - password_set
- token_view - secret_view
- invitation_used - invitation_used
- authorize_application - authorize_application
- source_linked - source_linked
@ -8023,6 +8269,12 @@ definitions:
items: items:
type: integer type: integer
uniqueItems: true uniqueItems: true
providers_obj:
description: ''
type: array
items:
$ref: '#/definitions/Provider'
readOnly: true
service_connection: service_connection:
title: Service connection title: Service connection
description: Select Service-Connection authentik should use to manage this description: Select Service-Connection authentik should use to manage this
@ -8030,9 +8282,36 @@ definitions:
type: string type: string
format: uuid format: uuid
x-nullable: true x-nullable: true
token_identifier:
title: Token identifier
type: string
readOnly: true
_config: _config:
title: config title: config
type: object type: object
OutpostHealth:
description: Outpost health status
type: object
properties:
last_seen:
title: Last seen
type: string
format: date-time
readOnly: true
version:
title: Version
type: string
readOnly: true
minLength: 1
version_should:
title: Version should
type: string
readOnly: true
minLength: 1
version_outdated:
title: Version outdated
type: boolean
readOnly: true
OpenIDConnectConfiguration: OpenIDConnectConfiguration:
title: Oidc configuration title: Oidc configuration
description: rest_framework Serializer for OIDC Configuration description: rest_framework Serializer for OIDC Configuration
@ -8170,6 +8449,21 @@ definitions:
description: User/Group Attribute used for the user part of the HTTP-Basic description: User/Group Attribute used for the user part of the HTTP-Basic
Header. If not set, the user's Email address is used. Header. If not set, the user's Email address is used.
type: string type: string
ServiceConnection:
description: ServiceConnection Serializer
required:
- name
type: object
properties:
pk:
title: Uuid
type: string
format: uuid
readOnly: true
name:
title: Name
type: string
minLength: 1
DockerServiceConnection: DockerServiceConnection:
description: DockerServiceConnection Serializer description: DockerServiceConnection Serializer
required: required:
@ -8347,7 +8641,7 @@ definitions:
- user_write - user_write
- suspicious_request - suspicious_request
- password_set - password_set
- token_view - secret_view
- invitation_used - invitation_used
- authorize_application - authorize_application
- source_linked - source_linked
@ -9157,6 +9451,10 @@ definitions:
type: string type: string
format: uuid format: uuid
x-nullable: true x-nullable: true
object_type:
title: Object type
type: string
readOnly: true
verbose_name: verbose_name:
title: Verbose name title: Verbose name
type: string type: string
@ -9165,10 +9463,6 @@ definitions:
title: Verbose name plural title: Verbose name plural
type: string type: string
readOnly: true readOnly: true
__type__:
title: 'type '
type: string
readOnly: true
LDAPSource: LDAPSource:
description: LDAP Source Serializer description: LDAP Source Serializer
required: required:
@ -9213,6 +9507,10 @@ definitions:
type: string type: string
format: uuid format: uuid
x-nullable: true x-nullable: true
object_type:
title: Object type
type: string
readOnly: true
verbose_name: verbose_name:
title: Verbose name title: Verbose name
type: string type: string
@ -9298,6 +9596,15 @@ definitions:
type: string type: string
format: uuid format: uuid
uniqueItems: true uniqueItems: true
LDAPSourceSyncStatus:
description: LDAP Sync status
type: object
properties:
last_sync:
title: Last sync
type: string
format: date-time
readOnly: true
OAuthSource: OAuthSource:
description: OAuth Source Serializer description: OAuth Source Serializer
required: required:
@ -9344,6 +9651,10 @@ definitions:
type: string type: string
format: uuid format: uuid
x-nullable: true x-nullable: true
object_type:
title: Object type
type: string
readOnly: true
verbose_name: verbose_name:
title: Verbose name title: Verbose name
type: string type: string
@ -9389,6 +9700,10 @@ definitions:
title: Consumer secret title: Consumer secret
type: string type: string
minLength: 1 minLength: 1
callback_url:
title: Callback url
type: string
readOnly: true
SAMLSource: SAMLSource:
description: SAMLSource Serializer description: SAMLSource Serializer
required: required:
@ -9397,6 +9712,11 @@ definitions:
- sso_url - sso_url
type: object type: object
properties: properties:
pk:
title: Pbm uuid
type: string
format: uuid
readOnly: true
name: name:
title: Name title: Name
description: Source's display Name. description: Source's display Name.
@ -9425,6 +9745,18 @@ definitions:
type: string type: string
format: uuid format: uuid
x-nullable: true x-nullable: true
object_type:
title: Object type
type: string
readOnly: true
verbose_name:
title: Verbose name
type: string
readOnly: true
verbose_name_plural:
title: Verbose name plural
type: string
readOnly: true
issuer: issuer:
title: Issuer title: Issuer
description: Also known as Entity ID. Defaults the Metadata URL. description: Also known as Entity ID. Defaults the Metadata URL.

140
web/package-lock.json generated
View File

@ -409,13 +409,13 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.0.tgz",
"integrity": "sha512-uMGfG7GFYK/nYutK/iqYJv6K/Xuog/vrRRZX9aEP4Zv1jsYXuvFUMDFLhUnc8WFv3D2R5QhNQL3VYKmvLS5zsQ==", "integrity": "sha512-DJgdGZW+8CFUTz5C/dnn4ONcUm2h2T0itWD85Ob5/V27Ndie8hUoX5HKyGssvR8sUMkAIlUc/AMK67Lqa3kBIQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/experimental-utils": "4.14.2", "@typescript-eslint/experimental-utils": "4.15.0",
"@typescript-eslint/scope-manager": "4.14.2", "@typescript-eslint/scope-manager": "4.15.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"lodash": "^4.17.15", "lodash": "^4.17.15",
@ -425,59 +425,115 @@
} }
}, },
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.0.tgz",
"integrity": "sha512-mV9pmET4C2y2WlyHmD+Iun8SAEqkLahHGBkGqDVslHkmoj3VnxnGP4ANlwuxxfq1BsKdl/MPieDbohCEQgKrwA==", "integrity": "sha512-V4vaDWvxA2zgesg4KPgEGiomWEBpJXvY4ZX34Y3qxK8LUm5I87L+qGIOTd9tHZOARXNRt9pLbblSKiYBlGMawg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.3", "@types/json-schema": "^7.0.3",
"@typescript-eslint/scope-manager": "4.14.2", "@typescript-eslint/scope-manager": "4.15.0",
"@typescript-eslint/types": "4.14.2", "@typescript-eslint/types": "4.15.0",
"@typescript-eslint/typescript-estree": "4.14.2", "@typescript-eslint/typescript-estree": "4.15.0",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0" "eslint-utils": "^2.0.0"
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.15.0.tgz",
"integrity": "sha512-ipqSP6EuUsMu3E10EZIApOJgWSpcNXeKZaFeNKQyzqxnQl8eQCbV+TSNsl+s2GViX2d18m1rq3CWgnpOxDPgHg==", "integrity": "sha512-L6Dtbq8Bc7g2aZwnIBETpmUa9XDKCMzKVwAArnGp5Mn7PRNFjf3mUzq8UeBjL3K8t311hvevnyqXAMSmxO8Gpg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "4.14.2", "@typescript-eslint/scope-manager": "4.15.0",
"@typescript-eslint/types": "4.14.2", "@typescript-eslint/types": "4.15.0",
"@typescript-eslint/typescript-estree": "4.14.2", "@typescript-eslint/typescript-estree": "4.15.0",
"debug": "^4.1.1" "debug": "^4.1.1"
}
}, },
"dependencies": {
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz",
"integrity": "sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg==", "integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "4.14.2", "@typescript-eslint/types": "4.15.0",
"@typescript-eslint/visitor-keys": "4.14.2" "@typescript-eslint/visitor-keys": "4.15.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz",
"integrity": "sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q==", "integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz",
"integrity": "sha512-ESiFl8afXxt1dNj8ENEZT12p+jl9PqRur+Y19m0Z/SPikGL6rqq4e7Me60SU9a2M28uz48/8yct97VQYaGl0Vg==", "integrity": "sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "4.14.2", "@typescript-eslint/types": "4.15.0",
"@typescript-eslint/visitor-keys": "4.14.2", "@typescript-eslint/visitor-keys": "4.15.0",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
}
},
"@typescript-eslint/visitor-keys": {
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz",
"integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.15.0",
"eslint-visitor-keys": "^2.0.0"
}
},
"globby": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz",
"integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==",
"dev": true,
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
}
}
}
},
"@typescript-eslint/scope-manager": {
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz",
"integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.15.0",
"@typescript-eslint/visitor-keys": "4.15.0"
}
},
"@typescript-eslint/types": {
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz",
"integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz",
"integrity": "sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.15.0",
"@typescript-eslint/visitor-keys": "4.15.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"globby": "^11.0.1", "globby": "^11.0.1",
"is-glob": "^4.0.1", "is-glob": "^4.0.1",
"lodash": "^4.17.15",
"semver": "^7.3.2", "semver": "^7.3.2",
"tsutils": "^3.17.1" "tsutils": "^3.17.1"
}, },
@ -499,12 +555,12 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "4.14.2", "version": "4.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz",
"integrity": "sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w==", "integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "4.14.2", "@typescript-eslint/types": "4.15.0",
"eslint-visitor-keys": "^2.0.0" "eslint-visitor-keys": "^2.0.0"
} }
}, },
@ -899,9 +955,9 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
}, },
"construct-style-sheets-polyfill": { "construct-style-sheets-polyfill": {
"version": "2.4.6", "version": "2.4.9",
"resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-2.4.6.tgz", "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-2.4.9.tgz",
"integrity": "sha512-lU0to7dFDjKslMF+M5NUa4s0RQMBRVyZMXvD/vp7vmjdEPgziTkHSfZHQxfoIvVWajWRJUVJMLfrMwcx8fTh4A==" "integrity": "sha512-kPXZXxsp7CTr/Vs29+omUA29wTrFplkdY6jqxyv0DDWC5Ro79WmwpboH2M9KiOclbtn8r81GCFtc7+t7OjRnCw=="
}, },
"copy-descriptor": { "copy-descriptor": {
"version": "0.1.1", "version": "0.1.1",
@ -3304,9 +3360,9 @@
"dev": true "dev": true
}, },
"typescript": { "typescript": {
"version": "4.1.3", "version": "4.1.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.4.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "integrity": "sha512-+Uru0t8qIRgjuCpiSPpfGuhHecMllk5Zsazj5LZvVsEStEjmIRRBZe+jHjGQvsgS7M1wONy2PQXd67EMyV6acg==",
"dev": true "dev": true
}, },
"uglify-js": { "uglify-js": {

View File

@ -18,7 +18,7 @@
"@types/codemirror": "0.0.108", "@types/codemirror": "0.0.108",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
"codemirror": "^5.59.2", "codemirror": "^5.59.2",
"construct-style-sheets-polyfill": "^2.4.6", "construct-style-sheets-polyfill": "^2.4.9",
"flowchart.js": "^1.15.0", "flowchart.js": "^1.15.0",
"lit-element": "^2.4.0", "lit-element": "^2.4.0",
"lit-html": "^1.3.0", "lit-html": "^1.3.0",
@ -30,8 +30,8 @@
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-typescript": "^8.1.1", "@rollup/plugin-typescript": "^8.1.1",
"@typescript-eslint/eslint-plugin": "^4.14.2", "@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.14.2", "@typescript-eslint/parser": "^4.15.0",
"eslint": "^7.19.0", "eslint": "^7.19.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-lit": "^1.3.0", "eslint-plugin-lit": "^1.3.0",
@ -41,6 +41,6 @@
"rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"ts-lit-plugin": "^1.2.1", "ts-lit-plugin": "^1.2.1",
"typescript": "^4.1.3" "typescript": "^4.1.4"
} }
} }

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments } from "./Client";
import { Provider } from "./Providers"; import { Provider } from "./Providers";
export class Application { export class Application {
@ -22,8 +22,8 @@ export class Application {
return DefaultClient.fetch<Application>(["core", "applications", slug]); return DefaultClient.fetch<Application>(["core", "applications", slug]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Application>> { static list(filter?: QueryArguments): Promise<AKResponse<Application>> {
return DefaultClient.fetch<PBResponse<Application>>(["core", "applications"], filter); return DefaultClient.fetch<AKResponse<Application>>(["core", "applications"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -7,6 +7,15 @@ export interface QueryArguments {
[key: string]: number | string | boolean | null; [key: string]: number | string | boolean | null;
} }
export interface BaseInheritanceModel {
object_type: string;
verbose_name: string;
verbose_name_plural: string;
}
export class Client { export class Client {
makeUrl(url: string[], query?: QueryArguments): string { makeUrl(url: string[], query?: QueryArguments): string {
let builtUrl = `/api/${VERSION}/${url.join("/")}/`; let builtUrl = `/api/${VERSION}/${url.join("/")}/`;
@ -85,7 +94,7 @@ export interface PBPagination {
end_index: number; end_index: number;
} }
export interface PBResponse<T> { export interface AKResponse<T> {
pagination: PBPagination; pagination: PBPagination;
results: Array<T>; results: Array<T>;

View File

@ -1,4 +1,4 @@
import { DefaultClient, QueryArguments, PBResponse } from "./Client"; import { DefaultClient, QueryArguments, AKResponse } from "./Client";
import { Event } from "./Events"; import { Event } from "./Events";
export class Notification { export class Notification {
@ -17,8 +17,8 @@ export class Notification {
return DefaultClient.fetch<Notification>(["events", "notifications", pk]); return DefaultClient.fetch<Notification>(["events", "notifications", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Notification>> { static list(filter?: QueryArguments): Promise<AKResponse<Notification>> {
return DefaultClient.fetch<PBResponse<Notification>>(["events", "notifications"], filter); return DefaultClient.fetch<AKResponse<Notification>>(["events", "notifications"], filter);
} }
static markSeen(pk: string): Promise<{seen: boolean}> { static markSeen(pk: string): Promise<{seen: boolean}> {

View File

@ -1,4 +1,4 @@
import { DefaultClient, QueryArguments, PBResponse } from "./Client"; import { DefaultClient, QueryArguments, AKResponse } from "./Client";
import { Group } from "./Groups"; import { Group } from "./Groups";
export class Rule { export class Rule {
@ -16,8 +16,8 @@ export class Rule {
return DefaultClient.fetch<Rule>(["events", "rules", pk]); return DefaultClient.fetch<Rule>(["events", "rules", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Rule>> { static list(filter?: QueryArguments): Promise<AKResponse<Rule>> {
return DefaultClient.fetch<PBResponse<Rule>>(["events", "rules"], filter); return DefaultClient.fetch<AKResponse<Rule>>(["events", "rules"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -1,4 +1,4 @@
import { DefaultClient, QueryArguments, PBResponse } from "./Client"; import { DefaultClient, QueryArguments, AKResponse } from "./Client";
export class Transport { export class Transport {
pk: string; pk: string;
@ -15,8 +15,8 @@ export class Transport {
return DefaultClient.fetch<Transport>(["events", "transports", pk]); return DefaultClient.fetch<Transport>(["events", "transports", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Transport>> { static list(filter?: QueryArguments): Promise<AKResponse<Transport>> {
return DefaultClient.fetch<PBResponse<Transport>>(["events", "transports"], filter); return DefaultClient.fetch<AKResponse<Transport>>(["events", "transports"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments } from "./Client";
export interface EventUser { export interface EventUser {
pk: number; pk: number;
@ -28,8 +28,8 @@ export class Event {
return DefaultClient.fetch<Event>(["events", "events", pk]); return DefaultClient.fetch<Event>(["events", "events", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Event>> { static list(filter?: QueryArguments): Promise<AKResponse<Event>> {
return DefaultClient.fetch<PBResponse<Event>>(["events", "events"], filter); return DefaultClient.fetch<AKResponse<Event>>(["events", "events"], filter);
} }
// events/events/top_per_user/?filter_action=authorize_application // events/events/top_per_user/?filter_action=authorize_application

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments } from "./Client";
export enum FlowDesignation { export enum FlowDesignation {
Authentication = "authentication", Authentication = "authentication",
@ -34,12 +34,12 @@ export class Flow {
return DefaultClient.fetch<{ diagram: string }>(["flows", "instances", slug, "diagram"]); return DefaultClient.fetch<{ diagram: string }>(["flows", "instances", slug, "diagram"]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Flow>> { static list(filter?: QueryArguments): Promise<AKResponse<Flow>> {
return DefaultClient.fetch<PBResponse<Flow>>(["flows", "instances"], filter); return DefaultClient.fetch<AKResponse<Flow>>(["flows", "instances"], filter);
} }
static cached(): Promise<number> { static cached(): Promise<number> {
return DefaultClient.fetch<PBResponse<Flow>>(["flows", "cached"]).then(r => { return DefaultClient.fetch<AKResponse<Flow>>(["flows", "cached"]).then(r => {
return r.pagination.count; return r.pagination.count;
}); });
} }
@ -76,8 +76,8 @@ export class FlowStageBinding {
return DefaultClient.fetch<FlowStageBinding>(["flows", "bindings", slug]); return DefaultClient.fetch<FlowStageBinding>(["flows", "bindings", slug]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<FlowStageBinding>> { static list(filter?: QueryArguments): Promise<AKResponse<FlowStageBinding>> {
return DefaultClient.fetch<PBResponse<FlowStageBinding>>(["flows", "bindings"], filter); return DefaultClient.fetch<AKResponse<FlowStageBinding>>(["flows", "bindings"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

40
web/src/api/Outposts.ts Normal file
View File

@ -0,0 +1,40 @@
import { DefaultClient, AKResponse, QueryArguments } from "./Client";
import { Provider } from "./Providers";
export interface OutpostHealth {
last_seen: number;
version: string;
version_should: string;
version_outdated: boolean;
}
export class Outpost {
pk: string;
name: string;
providers: number[];
providers_obj: Provider[];
service_connection?: string;
_config: QueryArguments;
token_identifier: string;
constructor() {
throw Error();
}
static get(pk: string): Promise<Outpost> {
return DefaultClient.fetch<Outpost>(["outposts", "outposts", pk]);
}
static list(filter?: QueryArguments): Promise<AKResponse<Outpost>> {
return DefaultClient.fetch<AKResponse<Outpost>>(["outposts", "outposts"], filter);
}
static health(pk: string): Promise<OutpostHealth[]> {
return DefaultClient.fetch<OutpostHealth[]>(["outposts", "outposts", pk, "health"]);
}
static adminUrl(rest: string): string {
return `/administration/outposts/${rest}`;
}
}

View File

@ -1,23 +1,26 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, BaseInheritanceModel, AKResponse, QueryArguments } from "./Client";
export class Policy { export class Policy implements BaseInheritanceModel {
pk: string; pk: string;
name: string; name: string;
constructor() { constructor() {
throw Error(); throw Error();
} }
object_type: string;
verbose_name: string;
verbose_name_plural: string;
static get(pk: string): Promise<Policy> { static get(pk: string): Promise<Policy> {
return DefaultClient.fetch<Policy>(["policies", "all", pk]); return DefaultClient.fetch<Policy>(["policies", "all", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Policy>> { static list(filter?: QueryArguments): Promise<AKResponse<Policy>> {
return DefaultClient.fetch<PBResponse<Policy>>(["policies", "all"], filter); return DefaultClient.fetch<AKResponse<Policy>>(["policies", "all"], filter);
} }
static cached(): Promise<number> { static cached(): Promise<number> {
return DefaultClient.fetch<PBResponse<Policy>>(["policies", "cached"]).then(r => { return DefaultClient.fetch<AKResponse<Policy>>(["policies", "cached"]).then(r => {
return r.pagination.count; return r.pagination.count;
}); });
} }

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments } from "./Client";
import { Policy } from "./Policies"; import { Policy } from "./Policies";
export class PolicyBinding { export class PolicyBinding {
@ -18,8 +18,8 @@ export class PolicyBinding {
return DefaultClient.fetch<PolicyBinding>(["policies", "bindings", pk]); return DefaultClient.fetch<PolicyBinding>(["policies", "bindings", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<PolicyBinding>> { static list(filter?: QueryArguments): Promise<AKResponse<PolicyBinding>> {
return DefaultClient.fetch<PBResponse<PolicyBinding>>(["policies", "bindings"], filter); return DefaultClient.fetch<AKResponse<PolicyBinding>>(["policies", "bindings"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments } from "./Client";
export class PropertyMapping { export class PropertyMapping {
pk: string; pk: string;
@ -16,8 +16,8 @@ export class PropertyMapping {
return DefaultClient.fetch<PropertyMapping>(["propertymappings", "all", pk]); return DefaultClient.fetch<PropertyMapping>(["propertymappings", "all", pk]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<PropertyMapping>> { static list(filter?: QueryArguments): Promise<AKResponse<PropertyMapping>> {
return DefaultClient.fetch<PBResponse<PropertyMapping>>(["propertymappings", "all"], filter); return DefaultClient.fetch<AKResponse<PropertyMapping>>(["propertymappings", "all"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -1,6 +1,6 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { BaseInheritanceModel, DefaultClient, AKResponse, QueryArguments } from "./Client";
export class Provider { export class Provider implements BaseInheritanceModel {
pk: number; pk: number;
name: string; name: string;
authorization_flow: string; authorization_flow: string;
@ -20,8 +20,8 @@ export class Provider {
return DefaultClient.fetch<Provider>(["providers", "all", id.toString()]); return DefaultClient.fetch<Provider>(["providers", "all", id.toString()]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Provider>> { static list(filter?: QueryArguments): Promise<AKResponse<Provider>> {
return DefaultClient.fetch<PBResponse<Provider>>(["providers", "all"], filter); return DefaultClient.fetch<AKResponse<Provider>>(["providers", "all"], filter);
} }
static adminUrl(rest: string): string { static adminUrl(rest: string): string {

View File

@ -1,6 +1,6 @@
import { DefaultClient, PBResponse, QueryArguments } from "./Client"; import { BaseInheritanceModel, DefaultClient, AKResponse, QueryArguments } from "./Client";
export class Source { export class Source implements BaseInheritanceModel {
pk: string; pk: string;
name: string; name: string;
slug: string; slug: string;
@ -11,12 +11,19 @@ export class Source {
constructor() { constructor() {
throw Error(); throw Error();
} }
object_type: string;
verbose_name: string;
verbose_name_plural: string;
static get(slug: string): Promise<Source> { static get(slug: string): Promise<Source> {
return DefaultClient.fetch<Source>(["sources", "all", slug]); return DefaultClient.fetch<Source>(["sources", "all", slug]);
} }
static list(filter?: QueryArguments): Promise<PBResponse<Source>> { static list(filter?: QueryArguments): Promise<AKResponse<Source>> {
return DefaultClient.fetch<PBResponse<Source>>(["sources", "all"], filter); return DefaultClient.fetch<AKResponse<Source>>(["sources", "all"], filter);
}
static adminUrl(rest: string): string {
return `/administration/sources/${rest}`;
} }
} }

View File

@ -1,4 +1,4 @@
import { DefaultClient, PBResponse } from "./Client"; import { DefaultClient, AKResponse } from "./Client";
let _globalMePromise: Promise<User>; let _globalMePromise: Promise<User>;
@ -22,7 +22,7 @@ export class User {
} }
static count(): Promise<number> { static count(): Promise<number> {
return DefaultClient.fetch<PBResponse<User>>(["core", "users"], { return DefaultClient.fetch<AKResponse<User>>(["core", "users"], {
"page_size": 1 "page_size": 1
}).then(r => { }).then(r => {
return r.pagination.count; return r.pagination.count;

View File

@ -0,0 +1,35 @@
import { DefaultClient } from "../Client";
import { Source } from "../Sources";
export class LDAPSource extends Source {
server_uri: string;
bind_cn: string;
start_tls: boolean
base_dn: string;
additional_user_dn: string;
additional_group_dn: string;
user_object_filter: string;
group_object_filter: string;
group_membership_field: string;
object_uniqueness_field: string;
sync_users: boolean;
sync_users_password: boolean;
sync_groups: boolean;
sync_parent_group?: string;
property_mappings: string[];
property_mappings_group: string[];
constructor() {
super();
throw Error();
}
static get(slug: string): Promise<LDAPSource> {
return DefaultClient.fetch<LDAPSource>(["sources", "ldap", slug]);
}
static syncStatus(slug: string): Promise<{ last_sync?: number }> {
return DefaultClient.fetch(["sources", "ldap", slug, "sync_status"]);
}
}

View File

@ -0,0 +1,22 @@
import { DefaultClient } from "../Client";
import { Source } from "../Sources";
export class OAuthSource extends Source {
provider_type: string;
request_token_url: string;
authorization_url: string;
access_token_url: string;
profile_url: string;
consumer_key: string;
callback_url: string;
constructor() {
super();
throw Error();
}
static get(slug: string): Promise<OAuthSource> {
return DefaultClient.fetch<OAuthSource>(["sources", "oauth", slug]);
}
}

View File

@ -127,6 +127,7 @@ select[multiple] {
.pf-c-card { .pf-c-card {
--pf-c-card--BackgroundColor: var(--ak-dark-background-light); --pf-c-card--BackgroundColor: var(--ak-dark-background-light);
} }
.pf-c-card__title,
.pf-c-card__header-main, .pf-c-card__header-main,
.pf-c-card__body { .pf-c-card__body {
color: var(--ak-dark-foreground); color: var(--ak-dark-foreground);

View File

@ -28,4 +28,4 @@ export const ColorStyles = css`
background-color: var(--pf-global--danger-color--100); background-color: var(--pf-global--danger-color--100);
} }
`; `;
export const VERSION = "2021.2.1-rc2"; export const VERSION = "2021.2.2-stable";

View File

@ -9,6 +9,9 @@ export class ActionButton extends SpinnerButton {
@property() @property()
url = ""; url = "";
@property()
method = "POST";
callAction(): void { callAction(): void {
if (this.isRunning === true) { if (this.isRunning === true) {
return; return;
@ -19,7 +22,7 @@ export class ActionButton extends SpinnerButton {
headers: { "X-CSRFToken": csrftoken }, headers: { "X-CSRFToken": csrftoken },
}); });
fetch(request, { fetch(request, {
method: "POST", method: this.method,
mode: "same-origin", mode: "same-origin",
}) })
.then((r) => { .then((r) => {

View File

@ -1,19 +1,11 @@
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
// @ts-ignore import { unsafeHTML } from "lit-html/directives/unsafe-html";
import ModalBoxStyle from "@patternfly/patternfly/components/ModalBox/modal-box.css";
// @ts-ignore
import BullseyeStyle from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
// @ts-ignore
import BackdropStyle from "@patternfly/patternfly/components/Backdrop/backdrop.css";
// @ts-ignore
import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
// @ts-ignore
import fa from "@fortawesome/fontawesome-free/css/solid.css";
import { convertToSlug } from "../../utils"; import { convertToSlug } from "../../utils";
import { SpinnerButton } from "./SpinnerButton"; import { SpinnerButton } from "./SpinnerButton";
import { PRIMARY_CLASS } from "../../constants"; import { PRIMARY_CLASS } from "../../constants";
import { showMessage } from "../messages/MessageContainer"; import { showMessage } from "../messages/MessageContainer";
import { COMMON_STYLES } from "../../common/styles";
@customElement("ak-modal-button") @customElement("ak-modal-button")
export class ModalButton extends LitElement { export class ModalButton extends LitElement {
@ -23,22 +15,23 @@ export class ModalButton extends LitElement {
@property({type: Boolean}) @property({type: Boolean})
open = false; open = false;
@property()
modal = "<slot name='modal'></slot>";
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return COMMON_STYLES.concat(
css` css`
:host { :host {
text-align: left; text-align: left;
} }
::slotted(*) { .pf-c-modal-box.pf-m-lg {
overflow-y: auto; overflow-y: auto;
} }
`, .pf-c-modal-box > .pf-c-button + * {
ModalBoxStyle, margin-right: 0;
BullseyeStyle, }
BackdropStyle, `
ButtonStyle, );
fa,
];
} }
constructor() { constructor() {
@ -52,7 +45,7 @@ export class ModalButton extends LitElement {
updateHandlers(): void { updateHandlers(): void {
// Ensure links close the modal // Ensure links close the modal
this.querySelectorAll<HTMLAnchorElement>("[slot=modal] a").forEach((a) => { this.shadowRoot?.querySelectorAll<HTMLAnchorElement>("a").forEach((a) => {
if (a.target == "_blank") { if (a.target == "_blank") {
return; return;
} }
@ -63,7 +56,7 @@ export class ModalButton extends LitElement {
}); });
}); });
// Make name field update slug field // Make name field update slug field
this.querySelectorAll<HTMLInputElement>("input[name=name]").forEach((input) => { this.shadowRoot?.querySelectorAll<HTMLInputElement>("input[name=name]").forEach((input) => {
const form = input.closest("form"); const form = input.closest("form");
if (form === null) { if (form === null) {
return; return;
@ -83,7 +76,7 @@ export class ModalButton extends LitElement {
}); });
}); });
// Ensure forms sends in AJAX // Ensure forms sends in AJAX
this.querySelectorAll<HTMLFormElement>("[slot=modal] form").forEach((form) => { this.shadowRoot?.querySelectorAll<HTMLFormElement>("form").forEach((form) => {
form.addEventListener("submit", (e) => { form.addEventListener("submit", (e) => {
e.preventDefault(); e.preventDefault();
const formData = new FormData(form); const formData = new FormData(form);
@ -95,16 +88,10 @@ export class ModalButton extends LitElement {
.then((response) => { .then((response) => {
return response.text(); return response.text();
}) })
.then((data) => { .then((responseData) => {
if (data.indexOf("csrfmiddlewaretoken") !== -1) { if (responseData.indexOf("csrfmiddlewaretoken") !== -1) {
const modalSlot = this.querySelector("[slot=modal]"); this.modal = responseData;
if (!modalSlot) {
console.debug("authentik/modalbutton: modal slot not found?");
return;
}
modalSlot.innerHTML = data;
console.debug("authentik/modalbutton: re-showing form"); console.debug("authentik/modalbutton: re-showing form");
this.updateHandlers();
} else { } else {
this.open = false; this.open = false;
console.debug("authentik/modalbutton: successful submit"); console.debug("authentik/modalbutton: successful submit");
@ -136,14 +123,9 @@ export class ModalButton extends LitElement {
fetch(request, { fetch(request, {
mode: "same-origin", mode: "same-origin",
}) })
.then((r) => r.text()) .then((response) => response.text())
.then((t) => { .then((responseData) => {
const modalSlot = this.querySelector("[slot=modal]"); this.modal = responseData;
if (!modalSlot) {
return;
}
modalSlot.innerHTML = t;
this.updateHandlers();
this.open = true; this.open = true;
this.querySelectorAll<SpinnerButton>("ak-spinner-button").forEach((sb) => { this.querySelectorAll<SpinnerButton>("ak-spinner-button").forEach((sb) => {
sb.setDone(PRIMARY_CLASS); sb.setDone(PRIMARY_CLASS);
@ -177,7 +159,7 @@ export class ModalButton extends LitElement {
> >
<i class="fas fa-times" aria-hidden="true"></i> <i class="fas fa-times" aria-hidden="true"></i>
</button> </button>
<slot name="modal"> </slot> ${unsafeHTML(this.modal)}
</div> </div>
</div> </div>
</div>`; </div>`;
@ -187,4 +169,8 @@ export class ModalButton extends LitElement {
return html` <slot name="trigger" @click=${() => this.onClick()}></slot> return html` <slot name="trigger" @click=${() => this.onClick()}></slot>
${this.open ? this.renderModal() : ""}`; ${this.open ? this.renderModal() : ""}`;
} }
updated(): void {
this.updateHandlers();
}
} }

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { Notification } from "../../api/EventNotification"; import { Notification } from "../../api/EventNotification";
import { COMMON_STYLES } from "../../common/styles"; import { COMMON_STYLES } from "../../common/styles";
@ -8,7 +8,7 @@ import { COMMON_STYLES } from "../../common/styles";
export class NotificationDrawer extends LitElement { export class NotificationDrawer extends LitElement {
@property({attribute: false}) @property({attribute: false})
notifications?: PBResponse<Notification>; notifications?: AKResponse<Notification>;
@property({type: Number}) @property({type: Number})
unread = 0; unread = 0;

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../../elements/table/Table"; import { Table, TableColumn } from "../../elements/table/Table";
import { PolicyBinding } from "../../api/PolicyBindings"; import { PolicyBinding } from "../../api/PolicyBindings";
@ -14,7 +14,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
@property() @property()
target?: string; target?: string;
apiEndpoint(page: number): Promise<PBResponse<PolicyBinding>> { apiEndpoint(page: number): Promise<AKResponse<PolicyBinding>> {
return PolicyBinding.list({ return PolicyBinding.list({
target: this.target || "", target: this.target || "",
ordering: "order", ordering: "order",

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { CSSResult, html, LitElement, property, TemplateResult } from "lit-element"; import { CSSResult, html, LitElement, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { COMMON_STYLES } from "../../common/styles"; import { COMMON_STYLES } from "../../common/styles";
import "./TablePagination"; import "./TablePagination";
@ -69,7 +69,7 @@ export class TableColumn {
} }
export abstract class Table<T> extends LitElement { export abstract class Table<T> extends LitElement {
abstract apiEndpoint(page: number): Promise<PBResponse<T>>; abstract apiEndpoint(page: number): Promise<AKResponse<T>>;
abstract columns(): TableColumn[]; abstract columns(): TableColumn[];
abstract row(item: T): TemplateResult[]; abstract row(item: T): TemplateResult[];
@ -84,7 +84,7 @@ export abstract class Table<T> extends LitElement {
} }
@property({attribute: false}) @property({attribute: false})
data?: PBResponse<T>; data?: AKResponse<T>;
@property({type: Number}) @property({type: Number})
page = 1; page = 1;

View File

@ -23,11 +23,11 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
new SidebarItem("Applications", "/applications").activeWhen( new SidebarItem("Applications", "/applications").activeWhen(
`^/applications/(?<slug>${SLUG_REGEX})$` `^/applications/(?<slug>${SLUG_REGEX})$`
), ),
new SidebarItem("Sources", "/administration/sources/").activeWhen( new SidebarItem("Sources", "/sources").activeWhen(
`^/sources/(?<slug>${SLUG_REGEX})$`, `^/sources/(?<slug>${SLUG_REGEX})$`,
), ),
new SidebarItem("Providers", "/providers"), new SidebarItem("Providers", "/providers"),
new SidebarItem("Outposts", "/administration/outposts/"), new SidebarItem("Outposts", "/outposts"),
new SidebarItem("Outpost Service Connections", "/administration/outpost_service_connections/"), new SidebarItem("Outpost Service Connections", "/administration/outpost_service_connections/"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
@ -41,7 +41,7 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
new SidebarItem("Flows").children( new SidebarItem("Flows").children(
new SidebarItem("Flows", "/administration/flows/").activeWhen(`^/flows/(?<slug>${SLUG_REGEX})$`), new SidebarItem("Flows", "/administration/flows/").activeWhen(`^/flows/(?<slug>${SLUG_REGEX})$`),
new SidebarItem("Stages", "/administration/stages/"), new SidebarItem("Stages", "/administration/stages/"),
new SidebarItem("Prompts", "/administration/stages/prompts/"), new SidebarItem("Prompts", "/administration/stages_prompts/"),
new SidebarItem("Invitations", "/administration/stages/invitations/"), new SidebarItem("Invitations", "/administration/stages/invitations/"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);

View File

@ -2,7 +2,7 @@ import { gettext } from "django";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { ifDefined } from "lit-html/directives/if-defined"; import { ifDefined } from "lit-html/directives/if-defined";
import { Application } from "../api/Applications"; import { Application } from "../api/Applications";
import { PBResponse } from "../api/Client"; import { AKResponse } from "../api/Client";
import { COMMON_STYLES } from "../common/styles"; import { COMMON_STYLES } from "../common/styles";
import { loading, truncate } from "../utils"; import { loading, truncate } from "../utils";
@ -52,7 +52,7 @@ export class LibraryApplication extends LitElement {
@customElement("ak-library") @customElement("ak-library")
export class LibraryPage extends LitElement { export class LibraryPage extends LitElement {
@property({attribute: false}) @property({attribute: false})
apps?: PBResponse<Application>; apps?: AKResponse<Application>;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return COMMON_STYLES; return COMMON_STYLES;

View File

@ -1,13 +1,13 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement } from "lit-element"; import { customElement } from "lit-element";
import { DefaultClient, PBResponse } from "../../../api/Client"; import { DefaultClient, AKResponse } from "../../../api/Client";
import { AdminStatus, AdminStatusCard } from "./AdminStatusCard"; import { AdminStatus, AdminStatusCard } from "./AdminStatusCard";
@customElement("ak-admin-status-card-workers") @customElement("ak-admin-status-card-workers")
export class WorkersStatusCard extends AdminStatusCard<number> { export class WorkersStatusCard extends AdminStatusCard<number> {
getPrimaryValue(): Promise<number> { getPrimaryValue(): Promise<number> {
return DefaultClient.fetch<PBResponse<number>>(["admin", "workers"]).then((r) => { return DefaultClient.fetch<AKResponse<number>>(["admin", "workers"]).then((r) => {
return r.pagination.count; return r.pagination.count;
}); });
} }

View File

@ -1,7 +1,7 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { Application } from "../../api/Applications"; import { Application } from "../../api/Applications";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage"; import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/ModalButton"; import "../../elements/buttons/ModalButton";
@ -26,7 +26,7 @@ export class ApplicationListPage extends TablePage<Application> {
@property() @property()
order = "name"; order = "name";
apiEndpoint(page: number): Promise<PBResponse<Application>> { apiEndpoint(page: number): Promise<AKResponse<Application>> {
return Application.list({ return Application.list({
ordering: this.order, ordering: this.order,
page: page, page: page,

View File

@ -65,13 +65,13 @@ export class EventInfo extends LitElement {
case "model_updated": case "model_updated":
case "model_deleted": case "model_deleted":
return html` return html`
<h3>${gettext("Affected model:")}</h3><hr> <h3>${gettext("Affected model:")}</h3>
${this.getModelInfo(this.event.context.model as EventContext)} ${this.getModelInfo(this.event.context.model as EventContext)}
`; `;
case "authorize_application": case "authorize_application":
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
<h3>${gettext("Authorized application:")}</h3><hr> <h3>${gettext("Authorized application:")}</h3>
${this.getModelInfo(this.event.context.authorized_application as EventContext)} ${this.getModelInfo(this.event.context.authorized_application as EventContext)}
</div> </div>
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
@ -83,15 +83,16 @@ export class EventInfo extends LitElement {
}), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)} }), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)}
</span> </span>
</div> </div>
</div>`; </div>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "login_failed": case "login_failed":
return html` return html`
<h3>${gettext(`Attempted to log in as ${this.event.context.username}`)}</h3> <h3>${gettext(`Attempted to log in as ${this.event.context.username}`)}</h3>
<ak-expand>${this.defaultResponse()}</ak-expand>`; <ak-expand>${this.defaultResponse()}</ak-expand>`;
case "token_view": case "secret_view":
return html` return html`
<h3>${gettext("Token:")}</h3><hr> <h3>${gettext("Secret:")}</h3>
${this.getModelInfo(this.event.context.token as EventContext)}`; ${this.getModelInfo(this.event.context.secret as EventContext)}`;
case "property_mapping_exception": case "property_mapping_exception":
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { Event } from "../../api/Events"; import { Event } from "../../api/Events";
import { TableColumn } from "../../elements/table/Table"; import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage"; import { TablePage } from "../../elements/table/TablePage";
@ -27,7 +27,7 @@ export class EventListPage extends TablePage<Event> {
@property() @property()
order = "-created"; order = "-created";
apiEndpoint(page: number): Promise<PBResponse<Event>> { apiEndpoint(page: number): Promise<AKResponse<Event>> {
return Event.list({ return Event.list({
ordering: this.order, ordering: this.order,
page: page, page: page,

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage"; import { TablePage } from "../../elements/table/TablePage";
import "../../elements/policies/BoundPoliciesList"; import "../../elements/policies/BoundPoliciesList";
@ -29,7 +29,7 @@ export class RuleListPage extends TablePage<Rule> {
@property() @property()
order = "name"; order = "name";
apiEndpoint(page: number): Promise<PBResponse<Rule>> { apiEndpoint(page: number): Promise<AKResponse<Rule>> {
return Rule.list({ return Rule.list({
ordering: this.order, ordering: this.order,
page: page, page: page,

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { DefaultClient, PBResponse } from "../../api/Client"; import { DefaultClient, AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage"; import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/ActionButton"; import "../../elements/buttons/ActionButton";
@ -27,7 +27,7 @@ export class TransportListPage extends TablePage<Transport> {
@property() @property()
order = "name"; order = "name";
apiEndpoint(page: number): Promise<PBResponse<Transport>> { apiEndpoint(page: number): Promise<AKResponse<Transport>> {
return Transport.list({ return Transport.list({
ordering: this.order, ordering: this.order,
page: page, page: page,

View File

@ -1,6 +1,6 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../../elements/table/Table"; import { Table, TableColumn } from "../../elements/table/Table";
import "../../elements/Tabs"; import "../../elements/Tabs";
@ -17,7 +17,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
@property() @property()
target?: string; target?: string;
apiEndpoint(page: number): Promise<PBResponse<FlowStageBinding>> { apiEndpoint(page: number): Promise<AKResponse<FlowStageBinding>> {
return FlowStageBinding.list({ return FlowStageBinding.list({
target: this.target || "", target: this.target || "",
ordering: "order", ordering: "order",

View File

@ -1,14 +1,10 @@
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
// @ts-ignore
import BullseyeStyle from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
// @ts-ignore
import SpinnerStyle from "@patternfly/patternfly/components/Spinner/spinner.css";
// @ts-ignore
import BackdropStyle from "@patternfly/patternfly/components/Backdrop/backdrop.css";
import { SpinnerSize } from "../../elements/Spinner"; import { SpinnerSize } from "../../elements/Spinner";
import { showMessage } from "../../elements/messages/MessageContainer"; import { showMessage } from "../../elements/messages/MessageContainer";
import { gettext } from "django"; import { gettext } from "django";
import { SentryIgnoredError } from "../../common/errors"; import { SentryIgnoredError } from "../../common/errors";
import { unsafeHTML } from "lit-html/directives/unsafe-html";
import { COMMON_STYLES } from "../../common/styles";
@customElement("ak-site-shell") @customElement("ak-site-shell")
export class SiteShell extends LitElement { export class SiteShell extends LitElement {
@ -23,8 +19,11 @@ export class SiteShell extends LitElement {
@property({type: Boolean}) @property({type: Boolean})
loading = false; loading = false;
@property({type: String})
body = "";
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return COMMON_STYLES.concat(
css` css`
:host, :host,
::slotted(*) { ::slotted(*) {
@ -36,11 +35,8 @@ export class SiteShell extends LitElement {
left: 0; left: 0;
width: 100%; width: 100%;
} }
`, `
BackdropStyle, );
BullseyeStyle,
SpinnerStyle,
];
} }
constructor() { constructor() {
@ -63,23 +59,22 @@ export class SiteShell extends LitElement {
} }
this.loading = true; this.loading = true;
fetch(this._url) fetch(this._url)
.then((r) => { .then((response) => {
if (r.ok) { if (response.ok) {
return r; return response;
} }
console.debug(`authentik/site-shell: Request failed ${this._url}`); console.debug(`authentik/site-shell: Request failed ${this._url}`);
window.location.hash = "#/"; window.location.hash = "#/";
showMessage({ showMessage({
level_tag: "error", level_tag: "error",
message: gettext(`Request failed: ${r.statusText}`), message: gettext(`Request failed: ${response.statusText}`),
}); });
this.loading = false; this.loading = false;
throw new SentryIgnoredError("Request failed"); throw new SentryIgnoredError("Request failed");
}) })
.then((r) => r.text()) .then((response) => response.text())
.then((text) => { .then((text) => {
bodySlot.innerHTML = text; this.body = text;
this.updateHandlers();
}) })
.then(() => { .then(() => {
setTimeout(() => { setTimeout(() => {
@ -90,7 +85,7 @@ export class SiteShell extends LitElement {
updateHandlers(): void { updateHandlers(): void {
// Ensure anchors only change the hash // Ensure anchors only change the hash
this.querySelectorAll<HTMLAnchorElement>("a:not(.ak-root-link)").forEach((a) => { this.shadowRoot?.querySelectorAll<HTMLAnchorElement>("a:not(.ak-root-link)").forEach((a) => {
if (a.href === "") { if (a.href === "") {
return; return;
} }
@ -104,13 +99,13 @@ export class SiteShell extends LitElement {
} }
}); });
// Create refresh buttons // Create refresh buttons
this.querySelectorAll("[role=ak-refresh]").forEach((rt) => { this.shadowRoot?.querySelectorAll("[role=ak-refresh]").forEach((rt) => {
rt.addEventListener("click", () => { rt.addEventListener("click", () => {
this.loadContent(); this.loadContent();
}); });
}); });
// Make get forms (search bar) notify us on submit so we can change the hash // Make get forms (search bar) notify us on submit so we can change the hash
this.querySelectorAll<HTMLFormElement>("form[method=get]").forEach((form) => { this.shadowRoot?.querySelectorAll<HTMLFormElement>("form[method=get]").forEach((form) => {
form.addEventListener("submit", (e) => { form.addEventListener("submit", (e) => {
e.preventDefault(); e.preventDefault();
const formData = new FormData(form); const formData = new FormData(form);
@ -119,7 +114,7 @@ export class SiteShell extends LitElement {
}); });
}); });
// Make forms with POST Method have a correct action set // Make forms with POST Method have a correct action set
this.querySelectorAll<HTMLFormElement>("form[method=post]").forEach((form) => { this.shadowRoot?.querySelectorAll<HTMLFormElement>("form[method=post]").forEach((form) => {
form.addEventListener("submit", (e) => { form.addEventListener("submit", (e) => {
e.preventDefault(); e.preventDefault();
const formData = new FormData(form); const formData = new FormData(form);
@ -131,11 +126,7 @@ export class SiteShell extends LitElement {
return response.text(); return response.text();
}) })
.then((data) => { .then((data) => {
const bodySlot = this.querySelector("[slot=body]"); this.body = data;
if (!bodySlot) {
return;
}
bodySlot.innerHTML = data;
this.updateHandlers(); this.updateHandlers();
}) })
.catch((e) => { .catch((e) => {
@ -157,6 +148,10 @@ export class SiteShell extends LitElement {
</div> </div>
</div>` </div>`
: ""} : ""}
<slot name="body"></slot>`; ${unsafeHTML(this.body)}`;
}
updated(): void {
this.updateHandlers();
} }
} }

View File

@ -0,0 +1,49 @@
import { gettext } from "django";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { until } from "lit-html/directives/until";
import { Outpost } from "../../api/Outposts";
import { COMMON_STYLES } from "../../common/styles";
@customElement("ak-outpost-health")
export class OutpostHealth extends LitElement {
@property()
outpostId?: string;
static get styles(): CSSResult[] {
return COMMON_STYLES;
}
render(): TemplateResult {
if (!this.outpostId) {
return html`<ak-spinner></ak-spinner>`;
}
return html`<ul>${until(Outpost.health(this.outpostId).then((oh) => {
if (oh.length === 0) {
return html`<li>
<ul>
<li role="cell">
<i class="fas fa-question-circle"></i>&nbsp;${gettext("Not available")}
</li>
</ul>
</li>`;
}
return oh.map((h) => {
return html`<li>
<ul>
<li role="cell">
<i class="fas fa-check pf-m-success"></i>&nbsp;${gettext(`Last seen: ${new Date(h.last_seen * 1000).toLocaleTimeString()}`)}
</li>
<li role="cell">
${h.version_outdated ?
html`<i class="fas fa-times pf-m-danger"></i>&nbsp;
${gettext(`${h.version}, should be ${h.version_should}`)}` :
html`<i class="fas fa-check pf-m-success"></i>&nbsp;${gettext(`Version: ${h.version}`)}`}
</li>
</ul>
</li>`;
});
}), html`<ak-spinner></ak-spinner>`)}</ul>`;
}
}

View File

@ -0,0 +1,122 @@
import { gettext } from "django";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { AKResponse } from "../../api/Client";
import { Outpost } from "../../api/Outposts";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import "./OutpostHealth";
import "../../elements/buttons/SpinnerButton";
import "../../elements/buttons/ModalButton";
import "../../elements/buttons/TokenCopyButton";
@customElement("ak-outpost-list")
export class OutpostListPage extends TablePage<Outpost> {
pageTitle(): string {
return "Outposts";
}
pageDescription(): string | undefined {
return "Outposts are deployments of authentik components to support different environments and protocols, like reverse proxies.";
}
pageIcon(): string {
return "pf-icon pf-icon-zone";
}
searchEnabled(): boolean {
return true;
}
apiEndpoint(page: number): Promise<AKResponse<Outpost>> {
return Outpost.list({
ordering: this.order,
page: page,
search: this.search || "",
});
}
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn("Providers"),
new TableColumn("Health and Version"),
new TableColumn(""),
];
}
@property()
order = "name";
row(item: Outpost): TemplateResult[] {
return [
html`${item.name}`,
html`<ul>${item.providers_obj.map((p) => {
return html`<li><a href="#/providers/${p.pk}">${p.name}</a></li>`;
})}</ul>`,
html`<ak-outpost-health outpostId=${item.pk}></ak-outpost-health>`,
html`
<ak-modal-button href="${Outpost.adminUrl(`${item.pk}/update`)}">
<ak-spinner-button slot="trigger" class="pf-m-secondary">
${gettext("Edit")}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>&nbsp;
<ak-modal-button href="${Outpost.adminUrl(`${item.pk}/delete`)}">
<ak-spinner-button slot="trigger" class="pf-m-danger">
${gettext("Delete")}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>&nbsp;
<ak-modal-button>
<button slot="trigger" class="pf-c-button pf-m-tertiary">
${gettext("View Deployment Info")}
</button>
<div slot="modal">
<div class="pf-c-modal-box__header">
<h1 class="pf-c-title pf-m-2xl" id="modal-title">${gettext("Outpost Deployment Info")}</h1>
</div>
<div class="pf-c-modal-box__body" id="modal-description">
<p><a href="https://goauthentik.io/docs/outposts/outposts/#deploy">${gettext("View deployment documentation")}</a></p>
<form class="pf-c-form">
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_HOST</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="${document.location.toString()}" />
</div>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_TOKEN</span>
</label>
<div>
<ak-token-copy-button identifier="${item.token_identifier}">
${gettext("Click to copy token")}
</ak-token-copy-button>
</div>
</div>
<h3>${gettext("If your authentik Instance is using a self-signed certificate, set this value.")}</h3>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_INSECURE</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="true" />
</div>
</form>
</div>
<footer class="pf-c-modal-box__footer pf-m-align-left">
<a class="pf-c-button pf-m-primary">${gettext("Close")}</a>
</footer>
</div>
</ak-modal-button>`,
];
}
renderToolbar(): TemplateResult {
return html`
<ak-modal-button href=${Outpost.adminUrl("create/")}>
<ak-spinner-button slot="trigger" class="pf-m-primary">
${gettext("Create")}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
${super.renderToolbar()}
`;
}
}

View File

@ -1,7 +1,7 @@
import { gettext } from "django"; import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { PropertyMapping } from "../../api/PropertyMapping"; import { PropertyMapping } from "../../api/PropertyMapping";
import { PBResponse } from "../../api/Client"; import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage"; import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/ModalButton"; import "../../elements/buttons/ModalButton";
@ -30,7 +30,7 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
@property({type: Boolean}) @property({type: Boolean})
hideManaged = false; hideManaged = false;
apiEndpoint(page: number): Promise<PBResponse<PropertyMapping>> { apiEndpoint(page: number): Promise<AKResponse<PropertyMapping>> {
return PropertyMapping.list({ return PropertyMapping.list({
ordering: this.order, ordering: this.order,
page: page, page: page,

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