Compare commits

..

202 Commits

Author SHA1 Message Date
86a4a7dcee release: 2022.3.3 2022-03-21 22:37:13 +01:00
73fe866cb6 website/docs: prepare 2022.3.3
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-21 22:37:01 +01:00
8b95e9f97a crypto: open files in read-only mode for importing (#2536)
closes #2535
2022-03-21 10:46:09 +01:00
a3eb72d160 website/integrations: Document using pfSense as Provider Integration (#2534)
* Add pfSense documentation

* add pfSense to sidebar

* Add pfsense secure setup

* rearrangement of sections for better clarity

* Add port value in unsecure setup

* change admonitions type for unsecure setup

* add `Test you setup` section

* add `Change pfSense default authentication backend` section

* Minor corrections

Co-authored-by: Danaël Giordana <danael@giordana.cc>
2022-03-21 10:45:30 +01:00
b418db6ecf build(deps): bump @babel/plugin-proposal-decorators in /web (#2537)
Bumps [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) from 7.17.2 to 7.17.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.8/packages/babel-plugin-proposal-decorators)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 10:02:15 +01:00
6cb1ab1d2b build(deps): bump country-flag-icons from 1.4.22 to 1.4.24 in /web (#2538)
Bumps [country-flag-icons](https://gitlab.com/catamphetamine/country-flag-icons) from 1.4.22 to 1.4.24.
- [Release notes](https://gitlab.com/catamphetamine/country-flag-icons/tags)
- [Changelog](https://gitlab.com/catamphetamine/country-flag-icons/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/country-flag-icons/compare/v1.4.22...v1.4.24)

---
updated-dependencies:
- dependency-name: country-flag-icons
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 10:01:09 +01:00
ae09dac720 build(deps): bump @babel/core from 7.17.7 to 7.17.8 in /web (#2539)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.17.7 to 7.17.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.8/packages/babel-core)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 10:00:53 +01:00
44c9ad19a7 build(deps): bump sentry-sdk from 1.5.7 to 1.5.8 (#2540)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.5.7 to 1.5.8.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/1.5.7...1.5.8)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 10:00:40 +01:00
554272a927 build(deps): bump paramiko from 2.10.2 to 2.10.3 (#2541)
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.10.2 to 2.10.3.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.10.2...2.10.3)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 10:00:26 +01:00
acf2af8f66 build(deps): bump github.com/go-openapi/runtime from 0.23.2 to 0.23.3 (#2542)
Bumps [github.com/go-openapi/runtime](https://github.com/go-openapi/runtime) from 0.23.2 to 0.23.3.
- [Release notes](https://github.com/go-openapi/runtime/releases)
- [Commits](https://github.com/go-openapi/runtime/compare/v0.23.2...v0.23.3)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-21 09:59:19 +01:00
b45a442447 outposts/ldap: fix contexts
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-19 18:28:27 +01:00
75a720ead1 outposts/ldap: prevent operations error from nil dereference (#2447)
closes #2526
2022-03-19 18:26:26 +01:00
615ce287ce Translate /web/src/locales/en.po in zh_CN (#2529)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_CN' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-19 17:46:55 +01:00
aa8d97249a Translate /web/src/locales/en.po in zh-Hans (#2530)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hans' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-19 17:46:46 +01:00
2390df17f1 Translate /web/src/locales/en.po in zh_TW (#2532)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_TW' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-19 17:46:34 +01:00
c022052539 Translate /web/src/locales/en.po in zh-Hant (#2531)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hant' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-19 17:46:21 +01:00
13c050e2a6 web: fix style for selected item in select in dark mode
closes #2528

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-18 21:20:11 +01:00
ef371b3750 web/admin: default to not include current session in flow play, add option to start with current session
closes #2527

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-18 19:41:11 +01:00
bb1f79347b build(deps): bump python (#2524)
Bumps python from 3.10.2-slim-bullseye to 3.10.3-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-18 10:14:07 +01:00
6ed0d6d124 build(deps-dev): bump pytest from 7.1.0 to 7.1.1 (#2525)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.1.0...7.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-18 10:13:54 +01:00
4ed60fe36b build(deps): bump postcss from 8.4.11 to 8.4.12 in /website (#2512) 2022-03-17 09:46:38 +01:00
ca9fa79095 build(deps): bump @types/grecaptcha from 3.0.3 to 3.0.4 in /web (#2513) 2022-03-17 09:46:23 +01:00
a2408cefcf build(deps): bump golang from 1.17.8-bullseye to 1.18.0-bullseye (#2511) 2022-03-17 09:45:44 +01:00
145eaa5de3 build(deps): bump prettier from 2.5.1 to 2.6.0 in /web (#2515) 2022-03-17 09:45:15 +01:00
1991c930f2 build(deps-dev): bump prettier from 2.5.1 to 2.6.0 in /website (#2516) 2022-03-17 09:44:55 +01:00
736f84b670 build(deps): bump country-flag-icons from 1.4.21 to 1.4.22 in /web (#2517) 2022-03-17 09:44:41 +01:00
d4d5c2675b build(deps): bump urllib3 from 1.26.8 to 1.26.9 (#2518) 2022-03-17 09:44:25 +01:00
be232e2b77 core: fix provider launch URL being prioritised over manually configured launch URL
closes #2493

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-16 10:26:55 +01:00
42389188ad web/elements: make SearchSelect optionally blankable
closes #2504

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-16 10:12:47 +01:00
1f6af8c221 web/admin: fix user defaulting to 0 when not set in PolicyBindingForm
closes #2496

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-16 10:12:47 +01:00
f4955e3e62 build(deps): bump github.com/stretchr/testify from 1.7.0 to 1.7.1 (#2502) 2022-03-16 09:31:14 +01:00
a8ef3096c1 build(deps): bump postcss from 8.4.8 to 8.4.11 in /website (#2498) 2022-03-16 09:29:05 +01:00
14f76b2575 build(deps): bump webcomponent-qr-code from 1.0.5 to 1.0.6 in /web (#2499) 2022-03-16 09:28:51 +01:00
50065d37b9 build(deps): bump @fortawesome/fontawesome-free in /web (#2500) 2022-03-16 09:28:40 +01:00
a54670fb91 build(deps): bump lit from 2.2.0 to 2.2.1 in /web (#2501) 2022-03-16 09:28:28 +01:00
51fda51cbf build(deps): bump goauthentik.io/api/v3 from 3.2022031.2 to 3.2022032.1 (#2503) 2022-03-16 09:27:22 +01:00
53d0205e86 outposts/proxy: use Prefix in ingress for k8s
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-15 19:01:08 +01:00
0f56d00959 website/docs: added example for custom user attributes (#2406)
* added example for custom user attributes

* simplified example

Co-authored-by: croudsarabi <constantin.roudsarabi@andrena.de>
2022-03-15 18:12:02 +01:00
b7a6fccdf9 web: Update Web API Client version (#2491)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-03-15 10:28:36 +01:00
522f49f48c Merge branch 'version-2022.3' 2022-03-15 10:07:40 +01:00
e685f11514 build(deps): bump @typescript-eslint/eslint-plugin in /web (#2486) 2022-03-15 09:35:36 +01:00
1841b9b4c6 build(deps): bump rollup from 2.70.0 to 2.70.1 in /web (#2485) 2022-03-15 09:32:23 +01:00
40e37a5c2c build(deps): bump @typescript-eslint/parser in /web (#2487) 2022-03-15 09:31:27 +01:00
ac838645a9 build(deps): bump @babel/core from 7.17.5 to 7.17.7 in /web (#2488) 2022-03-15 09:31:06 +01:00
be40d67c4d build(deps): bump paramiko from 2.10.1 to 2.10.2 (#2489) 2022-03-15 09:30:46 +01:00
700cc06f45 build(deps): bump goauthentik.io/api/v3 from 3.2022031.1 to 3.2022031.2 (#2490) 2022-03-15 09:30:30 +01:00
260a7aac63 release: 2022.3.2 2022-03-15 00:01:01 +01:00
37df054f4c website/docs: prepare 2022.3.2
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 23:59:38 +01:00
a3df414f24 sources/ldap: fix parent_group not being applied
closes #2464

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 22:13:20 +01:00
dcaa8d6322 flows: revert default flow user change
closes #2483

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 22:05:30 +01:00
e03dd70f2f web/user: filter applications by launch URL lto show empty state
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 21:15:47 +01:00
ceb894039e stages/authenticator_validate: fix passwordless flows not working
closes #2484

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 21:15:47 +01:00
a77616e942 website/integrations: add rocket.chat (#2470)
* Add files via upload

* Revert "Add Rocket.chat Instructions to Integrations Page"

* Adding Rocket.chat Integration documentation

* Adding Rocketchat to integrations/services

* Fix authentik name in 2 screenshots
2022-03-14 15:13:54 +01:00
47601a767b website/docs: fix invalid queries in docs
closes #2482
2022-03-14 12:38:22 +00:00
c7a825c393 lib: lower default sample rate 2022-03-14 12:38:14 +00:00
181c55aef1 website/docs: add http-basic to sonarr docs 2022-03-14 12:19:53 +01:00
631b1fcc29 web: Update Web API Client version (#2481)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-03-14 10:42:29 +01:00
54f170650a core: replace uid with uuid search
uid can't be searched it as its a computed field

closes #2480

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 10:35:55 +01:00
3bdb551e74 root: add make target for server and web
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-14 10:32:14 +01:00
96b2631ec4 build(deps): bump paramiko from 2.9.2 to 2.10.1 (#2475)
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.9.2 to 2.10.1.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.9.2...2.10.1)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:02:34 +01:00
4fffa6d2cc build(deps-dev): bump importlib-metadata from 4.11.2 to 4.11.3 (#2476)
Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 4.11.2 to 4.11.3.
- [Release notes](https://github.com/python/importlib_metadata/releases)
- [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst)
- [Commits](https://github.com/python/importlib_metadata/compare/v4.11.2...v4.11.3)

---
updated-dependencies:
- dependency-name: importlib-metadata
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:02:24 +01:00
e46c70e13d build(deps): bump @patternfly/patternfly from 4.179.1 to 4.183.1 in /web (#2474)
Bumps [@patternfly/patternfly](https://github.com/patternfly/patternfly) from 4.179.1 to 4.183.1.
- [Release notes](https://github.com/patternfly/patternfly/releases)
- [Changelog](https://github.com/patternfly/patternfly/blob/main/RELEASE-NOTES.md)
- [Commits](https://github.com/patternfly/patternfly/compare/prerelease-v4.179.1...prerelease-v4.183.1)

---
updated-dependencies:
- dependency-name: "@patternfly/patternfly"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:02:09 +01:00
7d4e7f84f4 build(deps): bump eslint from 8.10.0 to 8.11.0 in /web (#2473)
Bumps [eslint](https://github.com/eslint/eslint) from 8.10.0 to 8.11.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.10.0...v8.11.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:01:58 +01:00
d49640ca9b build(deps): bump goauthentik.io/api/v3 from 3.2022021.4 to 3.2022031.1 (#2477)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022021.4 to 3.2022031.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022021.4...v3.2022031.1)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:00:52 +01:00
ed2cf44471 build(deps-dev): bump pytest from 7.0.1 to 7.1.0 (#2478)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.1 to 7.1.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.0.1...7.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:00:30 +01:00
5b1d15276a build(deps): bump uvicorn from 0.17.5 to 0.17.6 (#2479)
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.17.5 to 0.17.6.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.17.5...0.17.6)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 10:00:09 +01:00
d9275a3350 web/elements: fix search-select hover background
closes #2471

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-13 01:58:40 +01:00
2e81dddc1d web/elements: fix search select background in dark mode
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#2471
2022-03-13 01:53:42 +01:00
abc73deda0 web/elements: fix error with blank SearchSelect elements in forms
closes #2469

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-11 20:36:54 +01:00
becec6b7d8 web: Update Web API Client version (#2468)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-03-11 19:10:27 +01:00
ab516f782b website/user: fix duplicate help text in prompts
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-11 19:05:41 +01:00
d7b3c545aa Merge branch 'version-2022.3' 2022-03-11 11:02:51 +01:00
81550d9d1d website/docs: add release notes to sidebar
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-11 10:59:19 +01:00
72e5768c2f build(deps): bump channels-redis from 3.3.1 to 3.4.0 (#2465) 2022-03-11 09:17:27 +01:00
11cf5fc472 build(deps): bump github.com/getsentry/sentry-go from 0.12.0 to 0.13.0 (#2466) 2022-03-11 09:17:05 +01:00
fedb81571d release: 2022.3.1 2022-03-10 19:12:29 +01:00
37528e1bba stages/authenticator_validate: fix lint
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-10 09:56:04 +01:00
97ef2a6f5f build(deps-dev): bump selenium from 4.1.2 to 4.1.3 (#2461) 2022-03-10 09:33:34 +01:00
cc1509cf57 stages/authenticator_validate: fix logic error when multiple authenticator devices can be selected
closes #2290

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-10 00:46:42 +01:00
0dfecc6ae2 stages/authenticator_*: fix device.confirmed being set incorrectly
closes #2330

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-10 00:19:49 +01:00
c1e4d78672 root: deprecate :stable tag
#2439

we haven't released an -rc release in a while and I don't really see a need for them anymore, so lets simplify the release process

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-09 23:48:32 +01:00
0ab427b5bb website/docs: prepare 2022.3 release
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-09 23:42:25 +01:00
a9f095d1d9 website/docs: add docs for different flow executors
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-09 23:36:09 +01:00
de17207c68 lib: fix default geoip path
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#2453
2022-03-09 21:57:29 +01:00
d9675695fe root: remove backup remainders
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-09 21:56:18 +01:00
ec7f372fa9 build(deps): bump @sentry/browser from 6.18.1 to 6.18.2 in /web (#2455)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 6.18.1 to 6.18.2.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/6.18.1...6.18.2)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 09:27:16 +01:00
8a675152e6 build(deps): bump @sentry/tracing from 6.18.1 to 6.18.2 in /web (#2456)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 6.18.1 to 6.18.2.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/6.18.1...6.18.2)

---
updated-dependencies:
- dependency-name: "@sentry/tracing"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 09:24:34 +01:00
228fe01f92 build(deps): bump sentry-sdk from 1.5.6 to 1.5.7 (#2457)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.5.6 to 1.5.7.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/1.5.6...1.5.7)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 09:23:35 +01:00
b9547ece49 build(deps): bump @typescript-eslint/eslint-plugin in /web (#2448)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.13.0 to 5.14.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.14.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 09:41:17 +01:00
6e9bc143bd build(deps): bump @typescript-eslint/parser in /web (#2449)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.13.0 to 5.14.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.14.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 09:40:28 +01:00
8cd4bf1be8 build(deps): bump rollup from 2.69.2 to 2.70.0 in /web (#2450)
Bumps [rollup](https://github.com/rollup/rollup) from 2.69.2 to 2.70.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.69.2...v2.70.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 09:38:55 +01:00
76660e4666 internal: add tests with querystring
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-07 22:03:36 +01:00
73b2e2cb82 build(deps): bump golang from 1.17.7-bullseye to 1.17.8-bullseye (#2440) 2022-03-07 09:30:47 +01:00
d741d6dcf1 build(deps): bump postcss from 8.4.7 to 8.4.8 in /website (#2441) 2022-03-07 09:30:28 +01:00
2575fa6db7 build(deps): bump rollup from 2.69.0 to 2.69.2 in /web (#2442) 2022-03-07 09:30:12 +01:00
7512c57a2e build(deps-dev): bump bandit from 1.7.3 to 1.7.4 (#2443) 2022-03-07 09:30:02 +01:00
e6e2dfd757 build(deps): bump github.com/go-openapi/runtime from 0.23.1 to 0.23.2 (#2444) 2022-03-07 09:29:40 +01:00
920d1f1b0e providers/oauth2: initial client_credentials grant support (#2437)
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-05 23:24:55 +01:00
680d4fc20d website/integrations: Remove extra trailing bracket in matrix config (#2435)
In the sample code, there was an extra training "}" in the localpart_template causing all usernames to be appended with "=7D" before the server designation, such as:

@[Username]=7D:[ServerName]
2022-03-04 21:31:25 +01:00
4d3b25ea66 web: fix lint
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-04 09:52:19 +01:00
5106c0d0c1 build(deps): bump twisted from 22.1.0 to 22.2.0 (#2431) 2022-03-04 09:36:08 +01:00
fd09ade054 build(deps): bump @docusaurus/preset-classic in /website (#2433) 2022-03-04 09:34:29 +01:00
01629fe9e3 build(deps): bump @docusaurus/plugin-client-redirects in /website (#2434) 2022-03-04 09:31:50 +01:00
5be97e98e4 web: update flow background
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 20:00:53 +01:00
b1fd801ceb tenants: fix syntax error in expression for locale 2022-03-03 11:50:46 +00:00
62a939b91d internal: bump api client to v3
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 10:40:07 +01:00
257ac04be4 website: fix go-get repo
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 10:32:23 +01:00
ec5e6c14a2 web: Update Web API Client version (#2429)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-03-03 10:22:49 +01:00
1e1d9f1bdd core/api: allow filtering users by uid, add uid to search
closes #2428

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 10:19:56 +01:00
da1ea51dad Translate /web/src/locales/en.po in zh_CN (#2421)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_CN' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-03 09:45:47 +01:00
6ee3b8d644 web: Update Web API Client version (#2420)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-03-03 09:45:37 +01:00
6155c69b7c Translate /web/src/locales/en.po in zh_TW (#2423)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_TW' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-03 09:45:20 +01:00
136d40d919 Translate /web/src/locales/en.po in zh-Hans (#2422)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hans' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-03 09:45:08 +01:00
bb1bb9e22a Translate /web/src/locales/en.po in zh-Hant (#2424)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hant' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-03-03 09:44:57 +01:00
05e84b63a2 build(deps): bump rollup from 2.68.0 to 2.69.0 in /web (#2426) 2022-03-03 09:29:43 +01:00
7ab55f7afa build(deps): bump @goauthentik/api in /web (#2425) 2022-03-03 09:24:23 +01:00
f5ec5245c5 build(deps): bump github.com/pires/go-proxyproto from 0.6.1 to 0.6.2 (#2427) 2022-03-03 09:24:03 +01:00
4f4f954693 core: customisable user settings (#2397)
* tenants: add user_settings flow, add basic flow and basic new executor

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

* web/user: use flow PromptStage instead of custom stage

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

* web/flows: add tenant to StageHost interface

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

* web/user: fix form missing component

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

* web/user: re-add success message

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

* web/user: improve support for multiple error messages

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

* stages/prompt: allow expressions in prompt placeholders

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

* stages/prompt: add tests

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

* flows: always set pending user

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

* flows: never cache stage configuration flow plans

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

* stages/user_write: fix error when pending user is anonymous user

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

* web/admin: add checkbox for prompt placeholder expression

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

* website/docs: add prompt expression docs

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

* stages/prompt: add ak-locale field type

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

* tenants: fix default policy

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

* web/user: add function to do global refresh

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

* web/flows: fix rendering of ak-locale

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

* tenants: fix default policy, add error handling to placeholder, fix locale attribute

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

* add tests

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 00:13:06 +01:00
c57fbcfd89 sources/oauth: log body when get_profile fails
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-02 20:37:42 +01:00
025fc3fe96 build(deps): bump actions/checkout from 2 to 3 (#2415)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-02 09:56:53 +01:00
4d079522c4 build(deps): bump django from 4.0.2 to 4.0.3 (#2416)
Bumps [django](https://github.com/django/django) from 4.0.2 to 4.0.3.
- [Release notes](https://github.com/django/django/releases)
- [Commits](https://github.com/django/django/compare/4.0.2...4.0.3)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-02 09:56:32 +01:00
08acc7ba41 providers/oauth2: fix invalid launch URL being generated 2022-03-01 15:29:21 +00:00
7bdd32506e web: cleanup default footer links 2022-03-01 15:27:21 +00:00
6283fedcd9 build(deps): bump @typescript-eslint/parser in /web (#2409) 2022-03-01 09:20:29 +01:00
7a0badc81b build(deps): bump @sentry/browser from 6.18.0 to 6.18.1 in /web (#2410) 2022-03-01 09:20:15 +01:00
1e134aa446 build(deps): bump typescript from 4.5.5 to 4.6.2 in /web (#2408) 2022-03-01 09:19:34 +01:00
27bc5489c5 build(deps): bump @sentry/tracing from 6.18.0 to 6.18.1 in /web (#2411) 2022-03-01 09:18:40 +01:00
2dca45917c build(deps): bump @typescript-eslint/eslint-plugin in /web (#2412) 2022-03-01 09:18:28 +01:00
66a4338b48 build(deps): bump actions/setup-python from 2 to 3 (#2413) 2022-03-01 09:18:14 +01:00
a4dfc7e068 build(deps): bump kubernetes from 22.6.0 to 23.3.0 (#2414) 2022-03-01 09:17:55 +01:00
f98a9bed9f build(deps-dev): bump bandit from 1.7.2 to 1.7.3 (#2403)
* build(deps-dev): bump bandit from 1.7.2 to 1.7.3

Bumps [bandit](https://github.com/PyCQA/bandit) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/PyCQA/bandit/releases)
- [Commits](https://github.com/PyCQA/bandit/compare/1.7.2...1.7.3)

---
updated-dependencies:
- dependency-name: bandit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

* sigh

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-28 10:13:51 +01:00
5d1bf4a0af website: update search config
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-28 09:54:47 +01:00
34635ab928 build(deps): bump @docusaurus/preset-classic in /website (#2400) 2022-02-28 09:16:48 +01:00
fabe1130c1 build(deps): bump @docusaurus/plugin-client-redirects in /website (#2401) 2022-02-28 09:14:22 +01:00
8feda9c2b1 build(deps): bump eslint from 8.9.0 to 8.10.0 in /web (#2399) 2022-02-28 09:14:03 +01:00
074928cac1 build(deps): bump wsproto from 1.0.0 to 1.1.0 (#2402) 2022-02-28 09:13:50 +01:00
2308f90270 build(deps-dev): bump importlib-metadata from 4.11.1 to 4.11.2 (#2404) 2022-02-28 09:13:10 +01:00
13adca0763 website/integrations: add hashicorp vault integration to website (#2363)
* add hashicorp vault

basic instructions for hashicorp vault

* removed auth0, updated redirect_uri's

removed auth0, updated redirect_uri's to include localhost

* Add hashicorp vault to app list

Add hashicorp-vault to the applications sidebar
2022-02-28 00:03:18 +01:00
50ded723d1 web: Update Web API Client version (#2398)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-02-27 15:17:11 +01:00
e9064509fe sources/oauth: Add Mailcow oauth source (#2380)
* Feat: Add Mailcow oauth source

* Feat: Add mailcow icon

* Run make

* Feat: Add tests

* Fix: Remainder from discord test

* Docs: Add mailcow oauth source docs

* Docs: add mailcow source to menu

* Fix: Mailcow provider type in test

* Fix: Formatting

* Fix: Doc file name
2022-02-27 15:06:02 +01:00
6fdf3ad3e5 internal/outpost: improve logging and add tests
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#2393
2022-02-26 22:29:56 +01:00
fb60cefb72 web/flows: fix rendering of help text on prompt stages
closes #2310

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 17:56:08 +01:00
61f7db314a web/admin: use searchable select field for users and groups in policy binding form
closes #2285

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 17:49:04 +01:00
ef7952cab3 web/admin: improve user and group management by showing related objects
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#2391
2022-02-26 17:48:25 +01:00
7e5d8624c8 web: fix locale change not updating all elements
closes #2365

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 16:29:12 +01:00
2c54be85be web: prioritise ?locale parameter over saved locale
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 16:24:29 +01:00
2f8dbe9b97 core: handle all exceptions for applications listing
closes #2382

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 16:08:38 +01:00
cebe44403c build(deps): bump prismjs from 1.26.0 to 1.27.0 in /web (#2394)
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.26.0 to 1.27.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.26.0...v1.27.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-26 15:18:37 +01:00
7261017e13 build(deps): bump prismjs from 1.26.0 to 1.27.0 in /website (#2395)
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.26.0 to 1.27.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.26.0...v1.27.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-26 15:18:26 +01:00
0b3d33f428 build(deps): bump @sentry/tracing from 6.17.9 to 6.18.0 in /web (#2385) 2022-02-25 09:58:43 +01:00
6f0cbd5fa6 build(deps): bump rapidoc from 9.1.8 to 9.2.0 in /website (#2383) 2022-02-25 09:58:02 +01:00
fb94aefd2f build(deps): bump postcss from 8.4.6 to 8.4.7 in /website (#2384) 2022-02-25 09:57:27 +01:00
c4c8390eff build(deps): bump rapidoc from 9.1.8 to 9.2.0 in /web (#2386) 2022-02-25 09:57:08 +01:00
8c2e4478fd build(deps): bump @sentry/browser from 6.17.9 to 6.18.0 in /web (#2387) 2022-02-25 09:56:58 +01:00
94029ee612 build(deps): bump actions/setup-node from 2 to 3.0.0 (#2388) 2022-02-25 09:56:20 +01:00
8db49f9eca build(deps-dev): bump selenium from 4.1.1 to 4.1.2 (#2389) 2022-02-25 09:56:06 +01:00
7bd25d90f4 core: compile backend translations (#2381) 2022-02-24 11:31:12 +01:00
133528ee90 website/docs: add email sender name explanation
closes #2378

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-24 10:39:33 +01:00
578bd8fcb3 Translate /web/src/locales/en.po in zh-Hans (#2370)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hans' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-24 10:12:10 +01:00
4c2ef95253 Translate /web/src/locales/en.po in zh_CN (#2371)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_CN' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-24 10:11:54 +01:00
702a59222d Apply translations in zh_CN (#2372)
translation completed for the source file '/locale/en/LC_MESSAGES/django.po'
on the 'zh_CN' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-24 10:11:43 +01:00
48e2121a75 Translate /web/src/locales/en.po in zh_TW (#2373)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_TW' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-24 10:11:32 +01:00
61249786ff Translate /web/src/locales/en.po in zh-Hant (#2374)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hant' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-24 10:11:20 +01:00
008af4ccce build(deps): bump @rollup/plugin-typescript from 8.3.0 to 8.3.1 in /web (#2375)
Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 8.3.0 to 8.3.1.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/typescript-v8.3.1/packages/typescript)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-24 10:10:43 +01:00
02e3010efe build(deps): bump @patternfly/patternfly from 4.171.1 to 4.179.1 in /web (#2376)
Bumps [@patternfly/patternfly](https://github.com/patternfly/patternfly) from 4.171.1 to 4.179.1.
- [Release notes](https://github.com/patternfly/patternfly/releases)
- [Changelog](https://github.com/patternfly/patternfly/blob/main/RELEASE-NOTES.md)
- [Commits](https://github.com/patternfly/patternfly/compare/prerelease-v4.171.1...prerelease-v4.179.1)

---
updated-dependencies:
- dependency-name: "@patternfly/patternfly"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-24 10:10:29 +01:00
aca4795e0c build(deps): bump @rollup/plugin-commonjs from 21.0.1 to 21.0.2 in /web (#2377)
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 21.0.1 to 21.0.2.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/commonjs-v21.0.2/packages/commonjs)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-24 10:10:04 +01:00
ff0febfecd build(deps-dev): bump selenium from 4.1.0 to 4.1.1 (#2379)
Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/SeleniumHQ/Selenium/releases)
- [Commits](https://github.com/SeleniumHQ/Selenium/commits)

---
updated-dependencies:
- dependency-name: selenium
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-24 10:09:53 +01:00
4daad4b514 web/admin: always show group/user policy options and display disclaimer
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-23 23:31:03 +01:00
677bcaadd7 core: add initial app launch url (#2367)
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-23 22:48:55 +01:00
c6e9ecdd37 build(deps): bump rollup from 2.67.3 to 2.68.0 in /web (#2358) 2022-02-23 09:50:51 +01:00
c9ecad6262 build(deps): bump @rollup/plugin-replace from 3.1.0 to 4.0.0 in /web (#2359) 2022-02-23 09:50:41 +01:00
e545b3b401 build(deps): bump @rollup/plugin-babel from 5.3.0 to 5.3.1 in /web (#2360) 2022-02-23 09:50:29 +01:00
fec96ea013 build(deps): bump sentry-sdk from 1.5.4 to 1.5.6 (#2361) 2022-02-23 09:50:16 +01:00
1ac1c50b67 build(deps): bump github.com/go-openapi/runtime from 0.23.0 to 0.23.1 (#2362) 2022-02-23 09:49:40 +01:00
d2f189c1d0 root: exempt enhancement issues from stale
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-22 20:34:39 +01:00
fb33906637 internal/ldap: fix panic when parsing lists with mixed types
closes #2355

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-22 19:56:55 +01:00
6d3a94f24f build(deps): bump @typescript-eslint/eslint-plugin in /web (#2352) 2022-02-22 09:45:12 +01:00
84f594e658 build(deps): bump codemirror from 5.65.1 to 5.65.2 in /web (#2353) 2022-02-22 09:43:58 +01:00
1486bd5ab2 build(deps): bump @typescript-eslint/parser in /web (#2354) 2022-02-22 09:43:36 +01:00
2c00f4da2d build(deps): bump rollup from 2.67.2 to 2.67.3 in /web (#2347)
Bumps [rollup](https://github.com/rollup/rollup) from 2.67.2 to 2.67.3.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.67.2...v2.67.3)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 09:40:51 +01:00
c10a23220b build(deps): bump rapidoc from 9.1.4 to 9.1.8 in /website (#2348)
Bumps [rapidoc](https://github.com/mrin9/RapiDoc) from 9.1.4 to 9.1.8.
- [Release notes](https://github.com/mrin9/RapiDoc/releases)
- [Commits](https://github.com/mrin9/RapiDoc/compare/v9.1.4...v9.1.8)

---
updated-dependencies:
- dependency-name: rapidoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 09:39:45 +01:00
f20243d545 build(deps): bump rapidoc from 9.1.4 to 9.1.8 in /web (#2349)
Bumps [rapidoc](https://github.com/mrin9/RapiDoc) from 9.1.4 to 9.1.8.
- [Release notes](https://github.com/mrin9/RapiDoc/releases)
- [Commits](https://github.com/mrin9/RapiDoc/compare/v9.1.4...v9.1.8)

---
updated-dependencies:
- dependency-name: rapidoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 09:39:32 +01:00
903c6422ad build(deps-dev): bump pylint-django from 2.5.1 to 2.5.2 (#2350)
Bumps [pylint-django](https://github.com/PyCQA/pylint-django) from 2.5.1 to 2.5.2.
- [Release notes](https://github.com/PyCQA/pylint-django/releases)
- [Changelog](https://github.com/PyCQA/pylint-django/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/PyCQA/pylint-django/compare/v2.5.1...v2.5.2)

---
updated-dependencies:
- dependency-name: pylint-django
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 09:39:19 +01:00
f5ab955536 build(deps-dev): bump coverage from 6.3.1 to 6.3.2 (#2351)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 6.3.1 to 6.3.2.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/6.3.1...6.3.2)

---
updated-dependencies:
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 09:39:03 +01:00
3a861f0497 Translate /web/src/locales/en.po in de (#2343)
translation completed for the source file '/web/src/locales/en.po'
on the 'de' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-18 12:43:41 +01:00
744f250d05 providers/proxy: always set rd param in addition to session to prevent wrong url in session
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-18 10:32:22 +01:00
83d435bd3b build(deps): bump lit from 2.1.4 to 2.2.0 in /web (#2339)
Bumps [lit](https://github.com/lit/lit/tree/HEAD/packages/lit) from 2.1.4 to 2.2.0.
- [Release notes](https://github.com/lit/lit/releases)
- [Changelog](https://github.com/lit/lit/blob/main/packages/lit/CHANGELOG.md)
- [Commits](https://github.com/lit/lit/commits/lit@2.2.0/packages/lit)

---
updated-dependencies:
- dependency-name: lit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-18 09:58:56 +01:00
945cdfe212 build(deps): bump @babel/core from 7.17.4 to 7.17.5 in /web (#2340)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.17.4 to 7.17.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.5/packages/babel-core)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-18 09:58:21 +01:00
fcc0963fab build(deps): bump lxml from 4.7.1 to 4.8.0 (#2341)
Bumps [lxml](https://github.com/lxml/lxml) from 4.7.1 to 4.8.0.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-4.7.1...lxml-4.8.0)

---
updated-dependencies:
- dependency-name: lxml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-18 09:58:07 +01:00
2ab4fcd757 build(deps): bump webauthn from 1.3.0 to 1.4.0 (#2342)
Bumps [webauthn](https://github.com/duo-labs/py_webauthn) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/duo-labs/py_webauthn/releases)
- [Changelog](https://github.com/duo-labs/py_webauthn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/duo-labs/py_webauthn/compare/v1.3.0...v1.4.0)

---
updated-dependencies:
- dependency-name: webauthn
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-18 09:57:53 +01:00
bfe31b15ad web: fix locale codes
closes #2332

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-17 22:37:54 +01:00
49c4b43f32 website/docs: better explain icon URL behaviour
closes #2337

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-17 22:37:17 +01:00
19b1f3a8c1 internal/outpost: fix logic error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-17 20:50:47 +01:00
80f218a6bf core: also handle TypeError for invalid app URL formatting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-17 18:23:11 +01:00
61aaa90226 build(deps): bump @sentry/browser from 6.17.8 to 6.17.9 in /web (#2331)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 6.17.8 to 6.17.9.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/6.17.8...6.17.9)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-17 10:24:21 +01:00
7fdda5a387 build(deps): bump @sentry/tracing from 6.17.8 to 6.17.9 in /web (#2333)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 6.17.8 to 6.17.9.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/6.17.8...6.17.9)

---
updated-dependencies:
- dependency-name: "@sentry/tracing"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-17 10:18:49 +01:00
94597fd2ad build(deps): bump uvicorn from 0.17.4 to 0.17.5 (#2334)
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.17.4 to 0.17.5.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.17.4...0.17.5)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-17 10:18:29 +01:00
09808883f4 build(deps-dev): bump pylint-django from 2.5.0 to 2.5.1 (#2335)
Bumps [pylint-django](https://github.com/PyCQA/pylint-django) from 2.5.0 to 2.5.1.
- [Release notes](https://github.com/PyCQA/pylint-django/releases)
- [Changelog](https://github.com/PyCQA/pylint-django/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/PyCQA/pylint-django/compare/v2.5.0...v2.5.1)

---
updated-dependencies:
- dependency-name: pylint-django
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-17 10:17:51 +01:00
81ecb85a55 Translate /web/src/locales/en.po in zh-Hans (#2326)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hans' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-16 13:41:44 +01:00
21bfaa3927 Translate /web/src/locales/en.po in zh_TW (#2327)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh_TW' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-16 13:41:36 +01:00
1c9c7be1c0 Translate /web/src/locales/en.po in zh-Hant (#2328)
translation completed for the source file '/web/src/locales/en.po'
on the 'zh-Hant' language.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2022-02-16 13:41:28 +01:00
5a11dc567e web: Update Web API Client version (#2325)
Signed-off-by: GitHub <noreply@github.com>

Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-02-16 11:33:54 +01:00
203 changed files with 19300 additions and 6667 deletions

View File

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

2
.github/stale.yml vendored
View File

@ -7,7 +7,7 @@ exemptLabels:
- pinned
- security
- pr_wanted
- enhancement/confirmed
- enhancement
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had

View File

@ -31,9 +31,9 @@ jobs:
- pending-migrations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
- id: cache-poetry
@ -50,8 +50,8 @@ jobs:
test-migrations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- id: cache-poetry
uses: actions/cache@v2.1.7
with:
@ -66,10 +66,10 @@ jobs:
test-migrations-from-stable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-python@v2
- uses: actions/setup-python@v3
- name: prepare variables
id: ev
run: |
@ -114,8 +114,8 @@ jobs:
test-unittest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- id: cache-poetry
uses: actions/cache@v2.1.7
with:
@ -141,8 +141,8 @@ jobs:
test-integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- id: cache-poetry
uses: actions/cache@v2.1.7
with:
@ -170,9 +170,9 @@ jobs:
test-e2e-provider:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -215,9 +215,9 @@ jobs:
test-e2e-rest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -279,7 +279,7 @@ jobs:
arch:
- 'linux/amd64'
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Set up Docker Buildx

View File

@ -14,7 +14,7 @@ jobs:
lint-golint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v2
with:
go-version: "^1.17"
@ -33,7 +33,7 @@ jobs:
test-unittest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v2
with:
go-version: "^1.17"
@ -66,7 +66,7 @@ jobs:
- 'linux/amd64'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Set up Docker Buildx
@ -110,11 +110,11 @@ jobs:
goos: [linux]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v2
with:
go-version: "^1.17"
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'

View File

@ -14,8 +14,8 @@ jobs:
lint-eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -32,8 +32,8 @@ jobs:
lint-prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -50,8 +50,8 @@ jobs:
lint-lit-analyse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -78,8 +78,8 @@ jobs:
- ci-web-mark
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'

View File

@ -28,7 +28,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@ -9,7 +9,7 @@ jobs:
build-server:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Set up Docker Buildx
@ -30,21 +30,12 @@ jobs:
with:
push: ${{ github.event_name == 'release' }}
tags: |
beryju/authentik:2022.2.1,
beryju/authentik:2022.3.3,
beryju/authentik:latest,
ghcr.io/goauthentik/server:2022.2.1,
ghcr.io/goauthentik/server:2022.3.3,
ghcr.io/goauthentik/server:latest
platforms: linux/amd64,linux/arm64
context: .
- name: Building Docker Image (stable)
if: ${{ github.event_name == 'release' && !contains('2022.2.1', 'rc') }}
run: |
docker pull beryju/authentik:latest
docker tag beryju/authentik:latest beryju/authentik:stable
docker push beryju/authentik:stable
docker pull ghcr.io/goauthentik/server:latest
docker tag ghcr.io/goauthentik/server:latest ghcr.io/goauthentik/server:stable
docker push ghcr.io/goauthentik/server:stable
build-outpost:
runs-on: ubuntu-latest
strategy:
@ -54,7 +45,7 @@ jobs:
- proxy
- ldap
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v2
with:
go-version: "^1.17"
@ -78,21 +69,12 @@ jobs:
with:
push: ${{ github.event_name == 'release' }}
tags: |
beryju/authentik-${{ matrix.type }}:2022.2.1,
beryju/authentik-${{ matrix.type }}:2022.3.3,
beryju/authentik-${{ matrix.type }}:latest,
ghcr.io/goauthentik/${{ matrix.type }}:2022.2.1,
ghcr.io/goauthentik/${{ matrix.type }}:2022.3.3,
ghcr.io/goauthentik/${{ matrix.type }}:latest
file: ${{ matrix.type }}.Dockerfile
platforms: linux/amd64,linux/arm64
- name: Building Docker Image (stable)
if: ${{ github.event_name == 'release' && !contains('2022.2.1', 'rc') }}
run: |
docker pull beryju/authentik-${{ matrix.type }}:latest
docker tag beryju/authentik-${{ matrix.type }}:latest beryju/authentik-${{ matrix.type }}:stable
docker push beryju/authentik-${{ matrix.type }}:stable
docker pull ghcr.io/goauthentik/${{ matrix.type }}:latest
docker tag ghcr.io/goauthentik/${{ matrix.type }}:latest ghcr.io/goauthentik/${{ matrix.type }}:stable
docker push ghcr.io/goauthentik/${{ matrix.type }}:stable
build-outpost-binary:
timeout-minutes: 120
runs-on: ubuntu-latest
@ -105,11 +87,11 @@ jobs:
goos: [linux, darwin]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v2
with:
go-version: "^1.17"
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
cache: 'npm'
@ -139,7 +121,7 @@ jobs:
- build-outpost-binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Run test suite in final docker images
run: |
echo "PG_PASS=$(openssl rand -base64 32)" >> .env
@ -155,7 +137,7 @@ jobs:
- build-outpost-binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Get static files from docker image
run: |
docker pull ghcr.io/goauthentik/server:latest
@ -170,7 +152,7 @@ jobs:
SENTRY_PROJECT: authentik
SENTRY_URL: https://sentry.beryju.org
with:
version: authentik@2022.2.1
version: authentik@2022.3.3
environment: beryjuorg-prod
sourcemaps: './web/dist'
url_prefix: '~/static/dist'

View File

@ -10,7 +10,7 @@ jobs:
name: Create Release from Tag
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Pre-release test
run: |
echo "PG_PASS=$(openssl rand -base64 32)" >> .env

View File

@ -20,8 +20,8 @@ jobs:
compile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- id: cache-poetry
uses: actions/cache@v2.1.7
with:

View File

@ -8,9 +8,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3.0.0
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'

View File

@ -16,7 +16,7 @@ ENV NODE_ENV=production
RUN cd /work/web && npm i && npm run build
# Stage 3: Build go proxy
FROM docker.io/golang:1.17.7-bullseye AS builder
FROM docker.io/golang:1.18.0-bullseye AS builder
WORKDIR /work
@ -32,7 +32,7 @@ COPY ./go.sum /work/go.sum
RUN go build -o /work/authentik ./cmd/server/main.go
# Stage 4: Run
FROM docker.io/python:3.10.2-slim-bullseye
FROM docker.io/python:3.10.3-slim-bullseye
LABEL org.opencontainers.image.url https://goauthentik.io
LABEL org.opencontainers.image.description goauthentik.io Main server image, see https://goauthentik.io for more info.
@ -60,9 +60,9 @@ RUN apt-get update && \
apt-get clean && \
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/ && \
adduser --system --no-create-home --uid 1000 --group --home /authentik authentik && \
mkdir -p /backups /certs /media && \
mkdir -p /certs /media && \
mkdir -p /authentik/.ssh && \
chown authentik:authentik /backups /certs /media /authentik/.ssh
chown authentik:authentik /certs /media /authentik/.ssh
COPY ./authentik/ /authentik
COPY ./pyproject.toml /

View File

@ -130,3 +130,13 @@ ci-pyright: ci--meta-debug
ci-pending-migrations: ci--meta-debug
./manage.py makemigrations --check
install:
poetry install
cd web && npm i
cd website && npm i
a: install
tmux \
new-session 'make run' \; \
split-window 'make web-watch'

View File

@ -6,8 +6,8 @@
| Version | Supported |
| ---------- | ------------------ |
| 2022.1.x | :white_check_mark: |
| 2022.2.x | :white_check_mark: |
| 2022.3.x | :white_check_mark: |
## Reporting a Vulnerability

View File

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

View File

@ -5,7 +5,6 @@ from django.core.cache import cache
from django.db.models import QuerySet
from django.http.response import HttpResponseBadRequest
from django.shortcuts import get_object_or_404
from django.utils.functional import SimpleLazyObject
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from guardian.shortcuts import get_objects_for_user
@ -49,18 +48,8 @@ class ApplicationSerializer(ModelSerializer):
def get_launch_url(self, app: Application) -> Optional[str]:
"""Allow formatting of launch URL"""
url = app.get_launch_url()
if not url:
return url
user = self.context["request"].user
if isinstance(user, SimpleLazyObject):
user._setup()
user = user._wrapped
try:
return url % user.__dict__
except ValueError as exc:
LOGGER.warning("Failed to format launch url", exc=exc)
return url
return app.get_launch_url(user)
class Meta:

View File

@ -24,7 +24,6 @@ from drf_spectacular.utils import (
from guardian.shortcuts import get_anonymous_user, get_objects_for_user
from rest_framework.decorators import action
from rest_framework.fields import CharField, DictField, JSONField, SerializerMethodField
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import (
@ -46,9 +45,6 @@ from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import LinkSerializer, PassiveSerializer, is_dict
from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION_IMPERSONATE_USER
from authentik.core.models import (
USER_ATTRIBUTE_CHANGE_EMAIL,
USER_ATTRIBUTE_CHANGE_NAME,
USER_ATTRIBUTE_CHANGE_USERNAME,
USER_ATTRIBUTE_SA,
USER_ATTRIBUTE_TOKEN_EXPIRING,
Group,
@ -57,7 +53,6 @@ from authentik.core.models import (
User,
)
from authentik.events.models import EventAction
from authentik.lib.config import CONFIG
from authentik.stages.email.models import EmailStage
from authentik.stages.email.tasks import send_mails
from authentik.stages.email.utils import TemplateEmailMessage
@ -126,43 +121,6 @@ class UserSelfSerializer(ModelSerializer):
"pk": group.pk,
}
def validate_email(self, email: str):
"""Check if the user is allowed to change their email"""
if self.instance.group_attributes().get(
USER_ATTRIBUTE_CHANGE_EMAIL, CONFIG.y_bool("default_user_change_email", True)
):
return email
if email != self.instance.email:
raise ValidationError("Not allowed to change email.")
return email
def validate_name(self, name: str):
"""Check if the user is allowed to change their name"""
if self.instance.group_attributes().get(
USER_ATTRIBUTE_CHANGE_NAME, CONFIG.y_bool("default_user_change_name", True)
):
return name
if name != self.instance.name:
raise ValidationError("Not allowed to change name.")
return name
def validate_username(self, username: str):
"""Check if the user is allowed to change their username"""
if self.instance.group_attributes().get(
USER_ATTRIBUTE_CHANGE_USERNAME, CONFIG.y_bool("default_user_change_username", True)
):
return username
if username != self.instance.username:
raise ValidationError("Not allowed to change username.")
return username
def save(self, **kwargs):
if self.instance:
attributes: dict = self.instance.attributes
attributes.update(self.validated_data.get("attributes", {}))
self.validated_data["attributes"] = attributes
return super().save(**kwargs)
class Meta:
model = User
@ -241,6 +199,7 @@ class UsersFilter(FilterSet):
)
is_superuser = BooleanFilter(field_name="ak_groups", lookup_expr="is_superuser")
uuid = CharFilter(field_name="uuid")
groups_by_name = ModelMultipleChoiceFilter(
field_name="ak_groups__name",
@ -290,7 +249,7 @@ class UserViewSet(UsedByMixin, ModelViewSet):
queryset = User.objects.none()
ordering = ["username"]
serializer_class = UserSerializer
search_fields = ["username", "name", "is_active", "email"]
search_fields = ["username", "name", "is_active", "email", "uuid"]
filterset_class = UsersFilter
def get_queryset(self): # pragma: no cover
@ -407,26 +366,6 @@ class UserViewSet(UsedByMixin, ModelViewSet):
update_session_auth_hash(self.request, user)
return Response(status=204)
@extend_schema(request=UserSelfSerializer, responses={200: SessionUserSerializer(many=False)})
@action(
methods=["PUT"],
detail=False,
pagination_class=None,
filter_backends=[],
permission_classes=[IsAuthenticated],
)
def update_self(self, request: Request) -> Response:
"""Allow users to change information on their own profile"""
data = UserSelfSerializer(instance=User.objects.get(pk=request.user.pk), data=request.data)
if not data.is_valid():
return Response(data.errors, status=400)
new_user = data.save()
# If we're impersonating, we need to update that user object
# since it caches the full object
if SESSION_IMPERSONATE_USER in request.session:
request.session[SESSION_IMPERSONATE_USER] = new_user
return Response({"user": data.data})
@permission_required("authentik_core.view_user", ["authentik_events.view_event"])
@extend_schema(responses={200: UserMetricsSerializer(many=False)})
@action(detail=True, pagination_class=None, filter_backends=[])

View File

@ -30,7 +30,7 @@ class InbuiltBackend(ModelBackend):
return
# Since we can't directly pass other variables to signals, and we want to log the method
# and the token used, we assume we're running in a flow and set a variable in the context
flow_plan: FlowPlan = request.session[SESSION_KEY_PLAN]
flow_plan: FlowPlan = request.session.get(SESSION_KEY_PLAN, FlowPlan(""))
flow_plan.context[PLAN_CONTEXT_METHOD] = method
flow_plan.context[PLAN_CONTEXT_METHOD_ARGS] = cleanse_dict(sanitize_dict(kwargs))
request.session[SESSION_KEY_PLAN] = flow_plan

View File

@ -14,7 +14,7 @@ from django.db import models
from django.db.models import Q, QuerySet, options
from django.http import HttpRequest
from django.templatetags.static import static
from django.utils.functional import cached_property
from django.utils.functional import SimpleLazyObject, cached_property
from django.utils.html import escape
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
@ -284,13 +284,24 @@ class Application(PolicyBindingModel):
return self.meta_icon.name
return self.meta_icon.url
def get_launch_url(self) -> Optional[str]:
def get_launch_url(self, user: Optional["User"] = None) -> Optional[str]:
"""Get launch URL if set, otherwise attempt to get launch URL based on provider."""
if self.meta_launch_url:
return self.meta_launch_url
url = None
if provider := self.get_provider():
return provider.launch_url
return None
url = provider.launch_url
if self.meta_launch_url:
url = self.meta_launch_url
if user and url:
if isinstance(user, SimpleLazyObject):
user._setup()
user = user._wrapped
try:
return url % user.__dict__
# pylint: disable=broad-except
except Exception as exc:
LOGGER.warning("Failed to format launch url", exc=exc)
return url
return url
def get_provider(self) -> Optional[Provider]:
"""Get casted provider instance"""

View File

@ -10,8 +10,8 @@
{% endblock %}
{% block body %}
<ak-message-container></ak-message-container>
<ak-interface-admin>
<ak-message-container data-refresh-on-locale="true"></ak-message-container>
<ak-interface-admin data-refresh-on-locale="true">
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
<div class="pf-c-empty-state" style="height: 100vh;">
<div class="pf-c-empty-state__content">

View File

@ -20,8 +20,8 @@
{% endblock %}
{% block body %}
<ak-message-container></ak-message-container>
<ak-flow-executor>
<ak-message-container data-refresh-on-locale="true"></ak-message-container>
<ak-flow-executor data-refresh-on-locale="true">
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
<div class="pf-c-empty-state" style="height: 100vh;">
<div class="pf-c-empty-state__content">

View File

@ -10,8 +10,8 @@
{% endblock %}
{% block body %}
<ak-message-container></ak-message-container>
<ak-interface-user>
<ak-message-container data-refresh-on-locale="true"></ak-message-container>
<ak-interface-user data-refresh-on-locale="true">
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
<div class="pf-c-empty-state" style="height: 100vh;">
<div class="pf-c-empty-state__content">

View File

@ -4,8 +4,10 @@ from rest_framework.test import APITestCase
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow
from authentik.policies.dummy.models import DummyPolicy
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.models import OAuth2Provider
class TestApplicationsAPI(APITestCase):
@ -13,8 +15,19 @@ class TestApplicationsAPI(APITestCase):
def setUp(self) -> None:
self.user = create_test_admin_user()
self.provider = OAuth2Provider.objects.create(
name="test",
redirect_uris="http://some-other-domain",
authorization_flow=Flow.objects.create(
name="test",
slug="test",
),
)
self.allowed = Application.objects.create(
name="allowed", slug="allowed", meta_launch_url="https://goauthentik.io/%(username)s"
name="allowed",
slug="allowed",
meta_launch_url="https://goauthentik.io/%(username)s",
provider=self.provider,
)
self.denied = Application.objects.create(name="denied", slug="denied")
PolicyBinding.objects.create(
@ -64,8 +77,19 @@ class TestApplicationsAPI(APITestCase):
"pk": str(self.allowed.pk),
"name": "allowed",
"slug": "allowed",
"provider": None,
"provider_obj": None,
"provider": self.provider.pk,
"provider_obj": {
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"authorization_flow": str(self.provider.authorization_flow.pk),
"component": "ak-provider-oauth2-form",
"meta_model_name": "authentik_providers_oauth2.oauth2provider",
"name": self.provider.name,
"pk": self.provider.pk,
"property_mappings": [],
"verbose_name": "OAuth2/OpenID Provider",
"verbose_name_plural": "OAuth2/OpenID Providers",
},
"launch_url": f"https://goauthentik.io/{self.user.username}",
"meta_launch_url": "https://goauthentik.io/%(username)s",
"meta_icon": None,
@ -100,8 +124,19 @@ class TestApplicationsAPI(APITestCase):
"pk": str(self.allowed.pk),
"name": "allowed",
"slug": "allowed",
"provider": None,
"provider_obj": None,
"provider": self.provider.pk,
"provider_obj": {
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"authorization_flow": str(self.provider.authorization_flow.pk),
"component": "ak-provider-oauth2-form",
"meta_model_name": "authentik_providers_oauth2.oauth2provider",
"name": self.provider.name,
"pk": self.provider.pk,
"property_mappings": [],
"verbose_name": "OAuth2/OpenID Provider",
"verbose_name_plural": "OAuth2/OpenID Providers",
},
"launch_url": f"https://goauthentik.io/{self.user.username}",
"meta_launch_url": "https://goauthentik.io/%(username)s",
"meta_icon": None,

View File

@ -0,0 +1,67 @@
"""Test Applications API"""
from unittest.mock import MagicMock, patch
from django.urls import reverse
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_tenant
from authentik.flows.models import Flow, FlowDesignation
from authentik.flows.tests import FlowTestCase
from authentik.tenants.models import Tenant
class TestApplicationsViews(FlowTestCase):
"""Test applications Views"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.allowed = Application.objects.create(
name="allowed", slug="allowed", meta_launch_url="https://goauthentik.io/%(username)s"
)
def test_check_redirect(self):
"""Test redirect"""
empty_flow = Flow.objects.create(
name="foo",
slug="foo",
designation=FlowDesignation.AUTHENTICATION,
)
tenant: Tenant = create_test_tenant()
tenant.flow_authentication = empty_flow
tenant.save()
response = self.client.get(
reverse(
"authentik_core:application-launch",
kwargs={"application_slug": self.allowed.slug},
),
follow=True,
)
self.assertEqual(response.status_code, 200)
with patch(
"authentik.flows.stage.StageView.get_pending_user", MagicMock(return_value=self.user)
):
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": empty_flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, f"https://goauthentik.io/{self.user.username}")
def test_check_redirect_auth(self):
"""Test redirect"""
self.client.force_login(self.user)
empty_flow = Flow.objects.create(
name="foo",
slug="foo",
designation=FlowDesignation.AUTHENTICATION,
)
tenant: Tenant = create_test_tenant()
tenant.flow_authentication = empty_flow
tenant.save()
response = self.client.get(
reverse(
"authentik_core:application-launch",
kwargs={"application_slug": self.allowed.slug},
),
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f"https://goauthentik.io/{self.user.username}")

View File

@ -2,12 +2,7 @@
from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.models import (
USER_ATTRIBUTE_CHANGE_EMAIL,
USER_ATTRIBUTE_CHANGE_NAME,
USER_ATTRIBUTE_CHANGE_USERNAME,
User,
)
from authentik.core.models import User
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_tenant
from authentik.flows.models import FlowDesignation
from authentik.lib.generators import generate_key
@ -22,51 +17,6 @@ class TestUsersAPI(APITestCase):
self.admin = create_test_admin_user()
self.user = User.objects.create(username="test-user")
def test_update_self(self):
"""Test update_self"""
self.admin.attributes["foo"] = "bar"
self.admin.save()
self.admin.refresh_from_db()
self.client.force_login(self.admin)
response = self.client.put(
reverse("authentik_api:user-update-self"), data={"username": "foo", "name": "foo"}
)
self.admin.refresh_from_db()
self.assertEqual(response.status_code, 200)
self.assertEqual(self.admin.attributes["foo"], "bar")
self.assertEqual(self.admin.username, "foo")
self.assertEqual(self.admin.name, "foo")
def test_update_self_name_denied(self):
"""Test update_self"""
self.admin.attributes[USER_ATTRIBUTE_CHANGE_NAME] = False
self.admin.save()
self.client.force_login(self.admin)
response = self.client.put(
reverse("authentik_api:user-update-self"), data={"username": "foo", "name": "foo"}
)
self.assertEqual(response.status_code, 400)
def test_update_self_username_denied(self):
"""Test update_self"""
self.admin.attributes[USER_ATTRIBUTE_CHANGE_USERNAME] = False
self.admin.save()
self.client.force_login(self.admin)
response = self.client.put(
reverse("authentik_api:user-update-self"), data={"username": "foo", "name": "foo"}
)
self.assertEqual(response.status_code, 400)
def test_update_self_email_denied(self):
"""Test update_self"""
self.admin.attributes[USER_ATTRIBUTE_CHANGE_EMAIL] = False
self.admin.save()
self.client.force_login(self.admin)
response = self.client.put(
reverse("authentik_api:user-update-self"), data={"email": "foo", "name": "foo"}
)
self.assertEqual(response.status_code, 400)
def test_metrics(self):
"""Test user's metrics"""
self.client.force_login(self.admin)

View File

@ -29,4 +29,4 @@ class UserSettingSerializer(PassiveSerializer):
component = CharField()
title = CharField()
configure_url = CharField(required=False)
icon_url = CharField()
icon_url = CharField(required=False)

View File

@ -5,7 +5,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import RedirectView
from django.views.generic.base import TemplateView
from authentik.core.views import impersonate
from authentik.core.views import apps, impersonate
from authentik.core.views.interface import FlowInterfaceView
from authentik.core.views.session import EndSessionView
@ -15,6 +15,12 @@ urlpatterns = [
login_required(RedirectView.as_view(pattern_name="authentik_core:if-user")),
name="root-redirect",
),
path(
# We have to use this format since everything else uses applications/o or applications/saml
"application/launch/<slug:application_slug>/",
apps.RedirectToAppLaunch.as_view(),
name="application-launch",
),
# Impersonation
path(
"-/impersonation/<int:user_id>/",

View File

@ -0,0 +1,75 @@
"""app views"""
from django.http import Http404, HttpRequest, HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from django.views import View
from authentik.core.models import Application
from authentik.flows.challenge import (
ChallengeResponse,
ChallengeTypes,
HttpChallengeResponse,
RedirectChallenge,
)
from authentik.flows.models import in_memory_stage
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.utils.urls import redirect_with_qs
from authentik.stages.consent.stage import (
PLAN_CONTEXT_CONSENT_HEADER,
PLAN_CONTEXT_CONSENT_PERMISSIONS,
)
from authentik.tenants.models import Tenant
class RedirectToAppLaunch(View):
"""Application launch view, redirect to the launch URL"""
def dispatch(self, request: HttpRequest, application_slug: str) -> HttpResponse:
app = get_object_or_404(Application, slug=application_slug)
# Check here if the application has any launch URL set, if not 404
launch = app.get_launch_url()
if not launch:
raise Http404
# Check if we're authenticated already, saves us the flow run
if request.user.is_authenticated:
return HttpResponseRedirect(app.get_launch_url(request.user))
# otherwise, do a custom flow plan that includes the application that's
# being accessed, to improve usability
tenant: Tenant = request.tenant
flow = tenant.flow_authentication
planner = FlowPlanner(flow)
planner.allow_empty_flows = True
plan = planner.plan(
request,
{
PLAN_CONTEXT_APPLICATION: app,
PLAN_CONTEXT_CONSENT_HEADER: _("You're about to sign into %(application)s.")
% {"application": app.name},
PLAN_CONTEXT_CONSENT_PERMISSIONS: [],
},
)
plan.insert_stage(in_memory_stage(RedirectToAppStage))
request.session[SESSION_KEY_PLAN] = plan
return redirect_with_qs("authentik_core:if-flow", request.GET, flow_slug=flow.slug)
class RedirectToAppStage(ChallengeStageView):
"""Final stage to be inserted after the user logs in"""
def get_challenge(self, *args, **kwargs) -> RedirectChallenge:
app = self.executor.plan.context[PLAN_CONTEXT_APPLICATION]
launch = app.get_launch_url(self.get_pending_user())
# sanity check to ensure launch is still set
if not launch:
raise Http404
return RedirectChallenge(
instance={
"type": ChallengeTypes.REDIRECT.value,
"to": launch,
}
)
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
return HttpChallengeResponse(self.get_challenge())

View File

@ -61,7 +61,7 @@ def certificate_discovery(self: MonitoredTask):
else:
cert_name = path.name.replace(path.suffix, "")
try:
with open(path, "r+", encoding="utf-8") as _file:
with open(path, "r", encoding="utf-8") as _file:
body = _file.read()
if "PRIVATE KEY" in body:
private_keys[cert_name] = ensure_private_key_valid(body)

View File

@ -13,7 +13,7 @@ from authentik.core.models import User
from authentik.events.models import cleanse_dict
from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException
from authentik.flows.markers import ReevaluateMarker, StageMarker
from authentik.flows.models import Flow, FlowStageBinding, Stage
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, Stage
from authentik.lib.config import CONFIG
from authentik.policies.engine import PolicyEngine
@ -156,14 +156,15 @@ class FlowPlanner:
# User is passing so far, check if we have a cached plan
cached_plan_key = cache_key(self.flow, user)
cached_plan = cache.get(cached_plan_key, None)
if cached_plan and self.use_cache:
self._logger.debug(
"f(plan): taking plan from cache",
key=cached_plan_key,
)
# Reset the context as this isn't factored into caching
cached_plan.context = default_context or {}
return cached_plan
if self.flow.designation not in [FlowDesignation.STAGE_CONFIGURATION]:
if cached_plan and self.use_cache:
self._logger.debug(
"f(plan): taking plan from cache",
key=cached_plan_key,
)
# Reset the context as this isn't factored into caching
cached_plan.context = default_context or {}
return cached_plan
self._logger.debug(
"f(plan): building plan",
)

View File

@ -36,7 +36,7 @@ error_reporting:
enabled: false
environment: customer
send_pii: false
sample_rate: 0.5
sample_rate: 0.3
# Global email settings
email:
@ -61,13 +61,9 @@ cookie_domain: null
disable_update_check: false
disable_startup_analytics: false
avatars: env://AUTHENTIK_AUTHENTIK__AVATARS?gravatar
geoip: "./GeoLite2-City.mmdb"
geoip: "/geoip/GeoLite2-City.mmdb"
footer_links:
- name: Documentation
href: https://goauthentik.io/docs/?utm_source=authentik
- name: authentik Website
href: https://goauthentik.io/?utm_source=authentik
footer_links: []
default_user_change_name: true
default_user_change_email: true

View File

@ -2,9 +2,12 @@
GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code"
GRANT_TYPE_REFRESH_TOKEN = "refresh_token" # nosec
GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials"
PROMPT_NONE = "none"
PROMPT_CONSNET = "consent"
PROMPT_LOGIN = "login"
SCOPE_OPENID = "openid"
SCOPE_OPENID_PROFILE = "profile"
SCOPE_OPENID_EMAIL = "email"

View File

@ -168,7 +168,7 @@ class TokenError(OAuth2Error):
https://tools.ietf.org/html/rfc6749#section-5.2
"""
_errors = {
errors = {
"invalid_request": "The request is otherwise malformed",
"invalid_client": "Client authentication failed (e.g., unknown client, "
"no client authentication included, or unsupported "
@ -188,7 +188,7 @@ class TokenError(OAuth2Error):
def __init__(self, error):
super().__init__()
self.error = error
self.description = self._errors[error]
self.description = self.errors[error]
class BearerTokenError(OAuth2Error):

View File

@ -7,7 +7,7 @@ from dataclasses import asdict, dataclass, field
from datetime import datetime
from hashlib import sha256
from typing import Any, Optional
from urllib.parse import urlparse
from urllib.parse import urlparse, urlunparse
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
@ -266,8 +266,8 @@ class OAuth2Provider(Provider):
if self.redirect_uris == "":
return None
main_url = self.redirect_uris.split("\n", maxsplit=1)[0]
launch_url = urlparse(main_url)
return main_url.replace(launch_url.path, "")
launch_url = urlparse(main_url)._replace(path="")
return urlunparse(launch_url)
@property
def component(self) -> str:

View File

@ -0,0 +1,174 @@
"""Test token view"""
from json import loads
from django.test import RequestFactory
from django.urls import reverse
from jwt import decode
from authentik.core.models import USER_ATTRIBUTE_SA, Application, Group, Token, TokenIntents
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
from authentik.lib.generators import generate_id, generate_key
from authentik.managed.manager import ObjectManager
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.constants import (
GRANT_TYPE_CLIENT_CREDENTIALS,
SCOPE_OPENID,
SCOPE_OPENID_EMAIL,
SCOPE_OPENID_PROFILE,
)
from authentik.providers.oauth2.errors import TokenError
from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping
from authentik.providers.oauth2.tests.utils import OAuthTestCase
class TestTokenClientCredentials(OAuthTestCase):
"""Test token (client_credentials) view"""
def setUp(self) -> None:
super().setUp()
ObjectManager().run()
self.factory = RequestFactory()
self.provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_id(),
client_secret=generate_key(),
authorization_flow=create_test_flow(),
redirect_uris="http://testserver",
signing_key=create_test_cert(),
)
self.provider.property_mappings.set(ScopeMapping.objects.all())
self.app = Application.objects.create(name="test", slug="test", provider=self.provider)
self.user = create_test_admin_user("sa")
self.user.attributes[USER_ATTRIBUTE_SA] = True
self.user.save()
self.token = Token.objects.create(
identifier="sa-token",
user=self.user,
intent=TokenIntents.INTENT_APP_PASSWORD,
expiring=False,
)
def test_wrong_user(self):
"""test invalid username"""
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": SCOPE_OPENID,
"client_id": self.provider.client_id,
"username": "saa",
"password": self.token.key,
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content.decode(),
{"error": "invalid_grant", "error_description": TokenError.errors["invalid_grant"]},
)
def test_wrong_token(self):
"""test invalid token"""
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": SCOPE_OPENID,
"client_id": self.provider.client_id,
"username": "sa",
"password": self.token.key + "foo",
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content.decode(),
{"error": "invalid_grant", "error_description": TokenError.errors["invalid_grant"]},
)
def test_non_sa(self):
"""test non service-account"""
self.user.attributes[USER_ATTRIBUTE_SA] = False
self.user.save()
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": SCOPE_OPENID,
"client_id": self.provider.client_id,
"username": "sa",
"password": self.token.key,
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content.decode(),
{"error": "invalid_grant", "error_description": TokenError.errors["invalid_grant"]},
)
def test_no_provider(self):
"""test no provider"""
self.app.provider = None
self.app.save()
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": SCOPE_OPENID,
"client_id": self.provider.client_id,
"username": "sa",
"password": self.token.key,
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content.decode(),
{"error": "invalid_grant", "error_description": TokenError.errors["invalid_grant"]},
)
def test_permission_denied(self):
"""test permission denied"""
group = Group.objects.create(name="foo")
PolicyBinding.objects.create(
group=group,
target=self.app,
order=0,
)
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": SCOPE_OPENID,
"client_id": self.provider.client_id,
"username": "sa",
"password": self.token.key,
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content.decode(),
{"error": "invalid_grant", "error_description": TokenError.errors["invalid_grant"]},
)
def test_successful(self):
"""test successful"""
response = self.client.post(
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"username": "sa",
"password": self.token.key,
},
)
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())
self.assertEqual(body["token_type"], "bearer")
_, alg = self.provider.get_jwt_key()
jwt = decode(
body["access_token"],
key=self.provider.signing_key.public_key,
algorithms=[alg],
audience=self.provider.client_id,
)
self.assertEqual(jwt["given_name"], self.user.name)
self.assertEqual(jwt["preferred_username"], self.user.username)

View File

@ -10,6 +10,7 @@ from authentik.core.models import Application
from authentik.providers.oauth2.constants import (
ACR_AUTHENTIK_DEFAULT,
GRANT_TYPE_AUTHORIZATION_CODE,
GRANT_TYPE_CLIENT_CREDENTIALS,
GRANT_TYPE_REFRESH_TOKEN,
SCOPE_OPENID,
)
@ -78,6 +79,7 @@ class ProviderInfoView(View):
GRANT_TYPE_AUTHORIZATION_CODE,
GRANT_TYPE_REFRESH_TOKEN,
GrantTypes.IMPLICIT,
GRANT_TYPE_CLIENT_CREDENTIALS,
],
"id_token_signing_alg_values_supported": [supported_alg],
# See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes

View File

@ -8,10 +8,13 @@ from django.http import HttpRequest, HttpResponse
from django.views import View
from structlog.stdlib import get_logger
from authentik.core.models import USER_ATTRIBUTE_SA, Application, Token, TokenIntents, User
from authentik.events.models import Event, EventAction
from authentik.lib.utils.time import timedelta_from_string
from authentik.policies.engine import PolicyEngine
from authentik.providers.oauth2.constants import (
GRANT_TYPE_AUTHORIZATION_CODE,
GRANT_TYPE_CLIENT_CREDENTIALS,
GRANT_TYPE_REFRESH_TOKEN,
)
from authentik.providers.oauth2.errors import TokenError, UserAuthError
@ -42,6 +45,7 @@ class TokenParams:
authorization_code: Optional[AuthorizationCode] = None
refresh_token: Optional[RefreshToken] = None
user: Optional[User] = None
code_verifier: Optional[str] = None
@ -75,50 +79,23 @@ class TokenParams:
)
def __post_init__(self, raw_code: str, raw_token: str, request: HttpRequest):
if self.provider.client_type == ClientTypes.CONFIDENTIAL:
if self.provider.client_secret != self.client_secret:
if self.grant_type in [GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN]:
if (
self.provider.client_type == ClientTypes.CONFIDENTIAL
and self.provider.client_secret != self.client_secret
):
LOGGER.warning(
"Invalid client secret: client does not have secret",
"Invalid client secret",
client_id=self.provider.client_id,
secret=self.provider.client_secret,
)
raise TokenError("invalid_client")
if self.grant_type == GRANT_TYPE_AUTHORIZATION_CODE:
self.__post_init_code(raw_code)
elif self.grant_type == GRANT_TYPE_REFRESH_TOKEN:
if not raw_token:
LOGGER.warning("Missing refresh token")
raise TokenError("invalid_grant")
try:
self.refresh_token = RefreshToken.objects.get(
refresh_token=raw_token, provider=self.provider
)
if self.refresh_token.is_expired:
LOGGER.warning(
"Refresh token is expired",
token=raw_token,
)
raise TokenError("invalid_grant")
# https://tools.ietf.org/html/rfc6749#section-6
# Fallback to original token's scopes when none are given
if not self.scope:
self.scope = self.refresh_token.scope
except RefreshToken.DoesNotExist:
LOGGER.warning(
"Refresh token does not exist",
token=raw_token,
)
raise TokenError("invalid_grant")
if self.refresh_token.revoked:
LOGGER.warning("Refresh token is revoked", token=raw_token)
Event.new(
action=EventAction.SUSPICIOUS_REQUEST,
message="Revoked refresh token was used",
token=raw_token,
).from_http(request)
raise TokenError("invalid_grant")
self.__post_init_refresh(raw_token, request)
elif self.grant_type == GRANT_TYPE_CLIENT_CREDENTIALS:
self.__post_init_client_credentials(request)
else:
LOGGER.warning("Invalid grant type", grant_type=self.grant_type)
raise TokenError("unsupported_grant_type")
@ -175,6 +152,77 @@ class TokenParams:
LOGGER.warning("Code challenge not matching")
raise TokenError("invalid_grant")
def __post_init_refresh(self, raw_token: str, request: HttpRequest):
if not raw_token:
LOGGER.warning("Missing refresh token")
raise TokenError("invalid_grant")
try:
self.refresh_token = RefreshToken.objects.get(
refresh_token=raw_token, provider=self.provider
)
if self.refresh_token.is_expired:
LOGGER.warning(
"Refresh token is expired",
token=raw_token,
)
raise TokenError("invalid_grant")
# https://tools.ietf.org/html/rfc6749#section-6
# Fallback to original token's scopes when none are given
if not self.scope:
self.scope = self.refresh_token.scope
except RefreshToken.DoesNotExist:
LOGGER.warning(
"Refresh token does not exist",
token=raw_token,
)
raise TokenError("invalid_grant")
if self.refresh_token.revoked:
LOGGER.warning("Refresh token is revoked", token=raw_token)
Event.new(
action=EventAction.SUSPICIOUS_REQUEST,
message="Revoked refresh token was used",
token=raw_token,
).from_http(request)
raise TokenError("invalid_grant")
def __post_init_client_credentials(self, request: HttpRequest):
# Authenticate user based on credentials
username = request.POST.get("username")
password = request.POST.get("password")
user = User.objects.filter(username=username).first()
if not user:
raise TokenError("invalid_grant")
token: Token = Token.filter_not_expired(
key=password, intent=TokenIntents.INTENT_APP_PASSWORD
).first()
if not token or token.user.uid != user.uid:
raise TokenError("invalid_grant")
self.user = user
if not self.user.attributes.get(USER_ATTRIBUTE_SA, False):
# Non-service accounts are not allowed
LOGGER.info("Non-service-account tried to use client credentials", user=self.user)
raise TokenError("invalid_grant")
Event.new(
action=EventAction.LOGIN,
PLAN_CONTEXT_METHOD="token",
PLAN_CONTEXT_METHOD_ARGS={
"identifier": token.identifier,
},
).from_http(request, user=user)
# Authorize user access
app = Application.objects.filter(provider=self.provider).first()
if not app or not app.provider:
raise TokenError("invalid_grant")
engine = PolicyEngine(app, self.user, request)
engine.build()
result = engine.result
if not result.passing:
LOGGER.info("User not authenticated for application", user=self.user, app=app)
raise TokenError("invalid_grant")
class TokenView(View):
"""Generate tokens for clients"""
@ -208,11 +256,14 @@ class TokenView(View):
self.params = TokenParams.parse(request, self.provider, client_id, client_secret)
if self.params.grant_type == GRANT_TYPE_AUTHORIZATION_CODE:
LOGGER.info("Converting authorization code to refresh token")
LOGGER.debug("Converting authorization code to refresh token")
return TokenResponse(self.create_code_response())
if self.params.grant_type == GRANT_TYPE_REFRESH_TOKEN:
LOGGER.info("Refreshing refresh token")
LOGGER.debug("Refreshing refresh token")
return TokenResponse(self.create_refresh_response())
if self.params.grant_type == GRANT_TYPE_CLIENT_CREDENTIALS:
LOGGER.debug("Client credentials grant")
return TokenResponse(self.create_client_credentials_response())
raise ValueError(f"Invalid grant_type: {self.params.grant_type}")
except TokenError as error:
return TokenResponse(error.create_dict(), status=400)
@ -292,3 +343,30 @@ class TokenView(View):
),
"id_token": self.params.provider.encode(refresh_token.id_token.to_dict()),
}
def create_client_credentials_response(self) -> dict[str, Any]:
"""See https://datatracker.ietf.org/doc/html/rfc6749#section-4.4"""
provider: OAuth2Provider = self.params.provider
refresh_token: RefreshToken = provider.create_refresh_token(
user=self.params.user,
scope=self.params.scope,
request=self.request,
)
refresh_token.id_token = refresh_token.create_id_token(
user=self.params.user,
request=self.request,
)
refresh_token.id_token.at_hash = refresh_token.at_hash
# Store the refresh_token.
refresh_token.save()
return {
"access_token": refresh_token.access_token,
"token_type": "bearer",
"expires_in": int(
timedelta_from_string(refresh_token.provider.token_validity).total_seconds()
),
"id_token": self.params.provider.encode(refresh_token.id_token.to_dict()),
}

View File

@ -129,7 +129,7 @@ class IngressReconciler(KubernetesObjectReconciler[V1Ingress]):
),
),
path="/outpost.goauthentik.io",
path_type="ImplementationSpecific",
path_type="Prefix",
)
]
),
@ -147,7 +147,7 @@ class IngressReconciler(KubernetesObjectReconciler[V1Ingress]):
),
),
path="/",
path_type="ImplementationSpecific",
path_type="Prefix",
)
]
),

View File

@ -37,6 +37,7 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
uniq = self._flatten(attributes[self._source.object_uniqueness_field])
try:
defaults = self.build_group_properties(group_dn, **attributes)
defaults["parent"] = self._source.sync_parent_group
self._logger.debug("Creating group with attributes", **defaults)
if "name" not in defaults:
raise IntegrityError("Name was not set by propertymappings")
@ -47,7 +48,6 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
Group,
{
f"attributes__{LDAP_UNIQUENESS}": uniq,
"parent": self._source.sync_parent_group,
},
defaults,
)

View File

@ -5,6 +5,7 @@ from django.db.models import Q
from django.test import TestCase
from authentik.core.models import Group, User
from authentik.core.tests.utils import create_test_admin_user
from authentik.events.models import Event, EventAction
from authentik.lib.generators import generate_key
from authentik.managed.manager import ObjectManager
@ -24,7 +25,7 @@ class LDAPSyncTests(TestCase):
def setUp(self):
ObjectManager().run()
self.source = LDAPSource.objects.create(
self.source: LDAPSource = LDAPSource.objects.create(
name="ldap",
slug="ldap",
base_dn="dc=goauthentik,dc=io",
@ -120,6 +121,9 @@ class LDAPSyncTests(TestCase):
self.source.property_mappings_group.set(
LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/default-name")
)
_user = create_test_admin_user()
parent_group = Group.objects.get(name=_user.username)
self.source.sync_parent_group = parent_group
connection = PropertyMock(return_value=mock_ad_connection(LDAP_PASSWORD))
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
self.source.save()
@ -127,8 +131,9 @@ class LDAPSyncTests(TestCase):
group_sync.sync()
membership_sync = MembershipLDAPSynchronizer(self.source)
membership_sync.sync()
group = Group.objects.filter(name="test-group")
self.assertTrue(group.exists())
group: Group = Group.objects.filter(name="test-group").first()
self.assertIsNotNone(group)
self.assertEqual(group.parent, parent_group)
def test_sync_groups_openldap(self):
"""Test group sync"""

View File

@ -17,6 +17,7 @@ AUTHENTIK_SOURCES_OAUTH_TYPES = [
"authentik.sources.oauth.types.okta",
"authentik.sources.oauth.types.reddit",
"authentik.sources.oauth.types.twitter",
"authentik.sources.oauth.types.mailcow",
]

View File

@ -44,7 +44,7 @@ class BaseOAuthClient:
response = self.do_request("get", profile_url, token=token)
response.raise_for_status()
except RequestException as exc:
LOGGER.warning("Unable to fetch user profile", exc=exc)
LOGGER.warning("Unable to fetch user profile", exc=exc, body=response.text)
return None
else:
return response.json()

View File

@ -11,7 +11,7 @@ def update_empty_urls(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
for source in OAuthSource.objects.using(db_alias).all():
changed = False
if source.access_token_url == "":
if source.access_token_url == "": # nosec
source.access_token_url = None
changed = True
if source.authorization_url == "":
@ -20,7 +20,7 @@ def update_empty_urls(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
if source.profile_url == "":
source.profile_url = None
changed = True
if source.request_token_url == "":
if source.request_token_url == "": # nosec
source.request_token_url = None
changed = True

View File

@ -111,6 +111,16 @@ class GitHubOAuthSource(OAuthSource):
verbose_name_plural = _("GitHub OAuth Sources")
class MailcowOAuthSource(OAuthSource):
"""Social Login using Mailcow."""
class Meta:
abstract = True
verbose_name = _("Mailcow OAuth Source")
verbose_name_plural = _("Mailcow OAuth Sources")
class TwitterOAuthSource(OAuthSource):
"""Social Login using Twitter.com"""

View File

@ -0,0 +1,38 @@
"""Mailcow Type tests"""
from django.test import TestCase
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.types.mailcow import MailcowOAuth2Callback
# https://community.mailcow.email/d/13-mailcow-oauth-json-format/2
MAILCOW_USER = {
"success": True,
"username": "email@example.com",
"identifier": "email@example.com",
"email": "email@example.com",
"full_name": "Example User",
"displayName": "Example User",
"created": "2020-05-15 11:33:08",
"modified": "2020-05-15 12:23:31",
"active": 1,
}
class TestTypeMailcow(TestCase):
"""OAuth Source tests"""
def setUp(self):
self.source = OAuthSource.objects.create(
name="test",
slug="test",
provider_type="mailcow",
authorization_url="",
profile_url="",
consumer_key="",
)
def test_enroll_context(self):
"""Test mailcow Enrollment context"""
ak_context = MailcowOAuth2Callback().get_user_enroll_context(MAILCOW_USER)
self.assertEqual(ak_context["email"], MAILCOW_USER["email"])
self.assertEqual(ak_context["name"], MAILCOW_USER["full_name"])

View File

@ -37,7 +37,7 @@ class AzureADClient(OAuth2Client):
)
response.raise_for_status()
except RequestException as exc:
LOGGER.warning("Unable to fetch user profile", exc=exc)
LOGGER.warning("Unable to fetch user profile", exc=exc, body=response.text)
return None
else:
return response.json()

View File

@ -0,0 +1,69 @@
"""Mailcow OAuth Views"""
from typing import Any, Optional
from requests.exceptions import RequestException
from structlog.stdlib import get_logger
from authentik.sources.oauth.clients.oauth2 import OAuth2Client
from authentik.sources.oauth.types.manager import MANAGER, SourceType
from authentik.sources.oauth.views.callback import OAuthCallback
from authentik.sources.oauth.views.redirect import OAuthRedirect
LOGGER = get_logger()
class MailcowOAuthRedirect(OAuthRedirect):
"""Mailcow OAuth2 Redirect"""
def get_additional_parameters(self, source): # pragma: no cover
return {
"scope": ["profile"],
}
class MailcowOAuth2Client(OAuth2Client):
"""MailcowOAuth2Client, for some reason, mailcow does not like the default headers"""
def get_profile_info(self, token: dict[str, str]) -> Optional[dict[str, Any]]:
"Fetch user profile information."
profile_url = self.source.type.profile_url or ""
if self.source.type.urls_customizable and self.source.profile_url:
profile_url = self.source.profile_url
try:
response = self.session.request(
"get",
f"{profile_url}?access_token={token['access_token']}",
)
response.raise_for_status()
except RequestException as exc:
LOGGER.warning("Unable to fetch user profile", exc=exc, body=response.text)
return None
else:
return response.json()
class MailcowOAuth2Callback(OAuthCallback):
"""Mailcow OAuth2 Callback"""
client_class = MailcowOAuth2Client
def get_user_enroll_context(
self,
info: dict[str, Any],
) -> dict[str, Any]:
return {
"email": info.get("email"),
"name": info.get("full_name"),
}
@MANAGER.type()
class MailcowType(SourceType):
"""Mailcow Type definition"""
callback_view = MailcowOAuth2Callback
redirect_view = MailcowOAuthRedirect
name = "Mailcow"
slug = "mailcow"
urls_customizable = True

View File

@ -61,7 +61,7 @@ class StaticDeviceViewSet(
):
"""Viewset for static authenticator devices"""
queryset = StaticDevice.objects.all()
queryset = StaticDevice.objects.filter(confirmed=True)
serializer_class = StaticDeviceSerializer
permission_classes = [OwnerPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]

View File

@ -55,7 +55,7 @@ class AuthenticatorStaticStageView(ChallengeStageView):
stage: AuthenticatorStaticStage = self.executor.current_stage
if SESSION_STATIC_DEVICE not in self.request.session:
device = StaticDevice(user=user, confirmed=True, name="Static Token")
device = StaticDevice(user=user, confirmed=False, name="Static Token")
tokens = []
for _ in range(0, stage.token_count):
tokens.append(StaticToken(device=device, token=StaticToken.random_token()))
@ -66,6 +66,7 @@ class AuthenticatorStaticStageView(ChallengeStageView):
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
"""Verify OTP Token"""
device: StaticDevice = self.request.session[SESSION_STATIC_DEVICE]
device.confirmed = True
device.save()
for token in self.request.session[SESSION_STATIC_TOKENS]:
token.save()

View File

@ -54,7 +54,7 @@ class TOTPDeviceViewSet(
):
"""Viewset for totp authenticator devices"""
queryset = TOTPDevice.objects.all()
queryset = TOTPDevice.objects.filter(confirmed=True)
serializer_class = TOTPDeviceSerializer
permission_classes = [OwnerPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]

View File

@ -42,6 +42,7 @@ class AuthenticatorTOTPChallengeResponse(ChallengeResponse):
"""Validate totp code"""
if self.device is not None:
if not self.device.verify_token(code):
self.device.confirmed = False
raise ValidationError(_("Code does not match"))
return code
@ -82,7 +83,7 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
if SESSION_TOTP_DEVICE not in self.request.session:
device = TOTPDevice(
user=user, confirmed=True, digits=stage.digits, name="TOTP Authenticator"
user=user, confirmed=False, digits=stage.digits, name="TOTP Authenticator"
)
self.request.session[SESSION_TOTP_DEVICE] = device
@ -91,6 +92,7 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
"""TOTP Token is validated by challenge"""
device: TOTPDevice = self.request.session[SESSION_TOTP_DEVICE]
device.confirmed = True
device.save()
del self.request.session[SESSION_TOTP_DEVICE]
return self.executor.stage_ok()

View File

@ -87,16 +87,20 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
def validate_selected_challenge(self, challenge: dict) -> dict:
"""Check which challenge the user has selected. Actual logic only used for SMS stage."""
# First check if the challenge is valid
allowed = False
for device_challenge in self.stage.request.session.get(SESSION_DEVICE_CHALLENGES):
if device_challenge.get("device_class", "") != challenge.get("device_class", ""):
raise ValidationError("invalid challenge selected")
if device_challenge.get("device_uid", "") != challenge.get("device_uid", ""):
raise ValidationError("invalid challenge selected")
if device_challenge.get("device_class", "") == challenge.get(
"device_class", ""
) and device_challenge.get("device_uid", "") == challenge.get("device_uid", ""):
allowed = True
if not allowed:
raise ValidationError("invalid challenge selected")
if challenge.get("device_class", "") != "sms":
return challenge
devices = SMSDevice.objects.filter(pk=int(challenge.get("device_uid", "0")))
if not devices.exists():
raise ValidationError("device does not exist")
raise ValidationError("invalid challenge selected")
select_challenge(self.stage.request, devices.first())
return challenge

View File

@ -1,6 +1,7 @@
"""Test validator stage"""
from unittest.mock import MagicMock, patch
from django.contrib.sessions.middleware import SessionMiddleware
from django.test.client import RequestFactory
from django.urls.base import reverse
from django_otp.plugins.otp_totp.models import TOTPDevice
@ -9,9 +10,11 @@ from webauthn.helpers import bytes_to_base64url
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction
from authentik.flows.stage import StageView
from authentik.flows.tests import FlowTestCase
from authentik.flows.views.executor import FlowExecutorView
from authentik.lib.generators import generate_id, generate_key
from authentik.lib.tests.utils import get_request
from authentik.lib.tests.utils import dummy_get_response, get_request
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
from authentik.stages.authenticator_validate.api import AuthenticatorValidateStageSerializer
from authentik.stages.authenticator_validate.challenge import (
@ -21,6 +24,10 @@ from authentik.stages.authenticator_validate.challenge import (
validate_challenge_webauthn,
)
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
from authentik.stages.authenticator_validate.stage import (
SESSION_DEVICE_CHALLENGES,
AuthenticatorValidationChallengeResponse,
)
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
from authentik.stages.identification.models import IdentificationStage, UserFields
@ -159,3 +166,39 @@ class AuthenticatorValidateStageTests(FlowTestCase):
):
with self.assertRaises(ValidationError):
validate_challenge_duo(duo_device.pk, request, self.user)
def test_validate_selected_challenge(self):
"""Test validate_selected_challenge"""
# Prepare request with session
request = self.request_factory.get("/")
middleware = SessionMiddleware(dummy_get_response)
middleware.process_request(request)
request.session[SESSION_DEVICE_CHALLENGES] = [
{
"device_class": "static",
"device_uid": "1",
},
{
"device_class": "totp",
"device_uid": "2",
},
]
request.session.save()
res = AuthenticatorValidationChallengeResponse()
res.stage = StageView(FlowExecutorView())
res.stage.request = request
with self.assertRaises(ValidationError):
res.validate_selected_challenge(
{
"device_class": "baz",
"device_uid": "quox",
}
)
res.validate_selected_challenge(
{
"device_class": "static",
"device_uid": "1",
}
)

View File

@ -49,6 +49,7 @@ class PromptSerializer(ModelSerializer):
"order",
"promptstage_set",
"sub_text",
"placeholder_expression",
]

View File

@ -0,0 +1,49 @@
# Generated by Django 4.0.2 on 2022-02-27 19:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_prompt", "0006_alter_prompt_type"),
]
operations = [
migrations.AddField(
model_name="prompt",
name="placeholder_expression",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="prompt",
name="type",
field=models.CharField(
choices=[
("text", "Text: Simple Text input"),
(
"text_read_only",
"Text (read-only): Simple Text input, but cannot be edited.",
),
(
"username",
"Username: Same as Text input, but checks for and prevents duplicate usernames.",
),
("email", "Email: Text field with Email type."),
(
"password",
"Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical.",
),
("number", "Number"),
("checkbox", "Checkbox"),
("date", "Date"),
("date-time", "Date Time"),
("separator", "Separator: Static Separator Line"),
("hidden", "Hidden: Hidden field, can be used to insert data into form."),
("static", "Static: Static value, displayed as-is."),
("ak-locale", "authentik: Selection of locales authentik supports"),
],
max_length=100,
),
),
]

View File

@ -3,6 +3,7 @@ from typing import Any, Optional
from uuid import uuid4
from django.db import models
from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _
from django.views import View
from rest_framework.fields import (
@ -16,15 +17,23 @@ from rest_framework.fields import (
ReadOnlyField,
)
from rest_framework.serializers import BaseSerializer
from structlog.stdlib import get_logger
from authentik.core.exceptions import PropertyMappingExpressionException
from authentik.core.expression import PropertyMappingEvaluator
from authentik.core.models import User
from authentik.flows.models import Stage
from authentik.lib.models import SerializerModel
from authentik.policies.models import Policy
LOGGER = get_logger()
class FieldTypes(models.TextChoices):
"""Field types an Prompt can be"""
# update website/docs/flow/stages/prompt.index.md
# Simple text field
TEXT = "text", _("Text: Simple Text input")
# Simple text field
@ -56,6 +65,8 @@ class FieldTypes(models.TextChoices):
HIDDEN = "hidden", _("Hidden: Hidden field, can be used to insert data into form.")
STATIC = "static", _("Static: Static value, displayed as-is.")
AK_LOCALE = "ak-locale", _("authentik: Selection of locales authentik supports")
class Prompt(SerializerModel):
"""Single Prompt, part of a prompt stage."""
@ -73,12 +84,33 @@ class Prompt(SerializerModel):
order = models.IntegerField(default=0)
placeholder_expression = models.BooleanField(default=False)
@property
def serializer(self) -> BaseSerializer:
from authentik.stages.prompt.api import PromptSerializer
return PromptSerializer
def get_placeholder(self, prompt_context: dict, user: User, request: HttpRequest) -> str:
"""Get fully interpolated placeholder"""
if self.field_key in prompt_context:
# We don't want to parse this as an expression since a user will
# be able to control the input
return prompt_context[self.field_key]
if self.placeholder_expression:
evaluator = PropertyMappingEvaluator()
evaluator.set_context(user, request, self, prompt_context=prompt_context)
try:
return evaluator.evaluate(self.placeholder)
except Exception as exc: # pylint:disable=broad-except
LOGGER.warning(
"failed to evaluate prompt placeholder",
exc=PropertyMappingExpressionException(str(exc)),
)
return self.placeholder
def field(self, default: Optional[Any]) -> CharField:
"""Get field type for Challenge and response"""
field_class = CharField
@ -93,10 +125,6 @@ class Prompt(SerializerModel):
field_class = EmailField
if self.type == FieldTypes.NUMBER:
field_class = IntegerField
if self.type == FieldTypes.HIDDEN:
field_class = HiddenField
kwargs["required"] = False
kwargs["default"] = self.placeholder
if self.type == FieldTypes.CHECKBOX:
field_class = BooleanField
kwargs["required"] = False
@ -104,13 +132,22 @@ class Prompt(SerializerModel):
field_class = DateField
if self.type == FieldTypes.DATE_TIME:
field_class = DateTimeField
if self.type == FieldTypes.SEPARATOR:
kwargs["required"] = False
kwargs["label"] = ""
if self.type == FieldTypes.HIDDEN:
field_class = HiddenField
kwargs["required"] = False
kwargs["default"] = self.placeholder
if self.type == FieldTypes.STATIC:
kwargs["default"] = self.placeholder
kwargs["required"] = False
kwargs["label"] = ""
if self.type == FieldTypes.SEPARATOR:
kwargs["required"] = False
kwargs["label"] = ""
if self.type == FieldTypes.AK_LOCALE:
kwargs["allow_blank"] = True
if default:
kwargs["default"] = default
# May not set both `required` and `default`

View File

@ -165,13 +165,14 @@ class PromptStageView(ChallengeStageView):
response_class = PromptChallengeResponse
def get_challenge(self, *args, **kwargs) -> Challenge:
fields = list(self.executor.current_stage.fields.all().order_by("order"))
fields: list[Prompt] = list(self.executor.current_stage.fields.all().order_by("order"))
serializers = []
context_prompt = self.executor.plan.context.get(PLAN_CONTEXT_PROMPT, {})
for field in fields:
data = StagePromptSerializer(field).data
if field.field_key in context_prompt:
data["placeholder"] = context_prompt.get(field.field_key)
data["placeholder"] = field.get_placeholder(
context_prompt, self.get_pending_user(), self.request
)
serializers.append(data)
challenge = PromptChallenge(
data={

View File

@ -1,16 +1,17 @@
"""Prompt tests"""
from unittest.mock import MagicMock, patch
from django.test import RequestFactory
from django.urls import reverse
from rest_framework.exceptions import ErrorDetail
from authentik.core.models import User
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.markers import StageMarker
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
from authentik.flows.planner import FlowPlan
from authentik.flows.tests import FlowTestCase
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.generators import generate_id
from authentik.policies.expression.models import ExpressionPolicy
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT, PromptChallengeResponse
@ -21,8 +22,8 @@ class TestPromptStage(FlowTestCase):
def setUp(self):
super().setUp()
self.user = User.objects.create(username="unittest", email="test@beryju.org")
self.user = create_test_admin_user()
self.factory = RequestFactory()
self.flow = Flow.objects.create(
name="test-prompt",
slug="test-prompt",
@ -219,3 +220,95 @@ class TestPromptStage(FlowTestCase):
self.assertNotEqual(challenge_response.validated_data["hidden_prompt"], "foo")
self.assertEqual(challenge_response.validated_data["hidden_prompt"], "hidden")
self.assertNotEqual(challenge_response.validated_data["static_prompt"], "foo")
def test_prompt_placeholder(self):
"""Test placeholder and expression"""
context = {
"foo": generate_id(),
}
prompt: Prompt = Prompt(
field_key="text_prompt_expression",
label="TEXT_LABEL",
type=FieldTypes.TEXT,
placeholder="return prompt_context['foo']",
placeholder_expression=True,
)
self.assertEqual(
prompt.get_placeholder(context, self.user, self.factory.get("/")), context["foo"]
)
context["text_prompt_expression"] = generate_id()
self.assertEqual(
prompt.get_placeholder(context, self.user, self.factory.get("/")),
context["text_prompt_expression"],
)
self.assertNotEqual(
prompt.get_placeholder(context, self.user, self.factory.get("/")), context["foo"]
)
def test_prompt_placeholder_error(self):
"""Test placeholder and expression"""
context = {}
prompt: Prompt = Prompt(
field_key="text_prompt_expression",
label="TEXT_LABEL",
type=FieldTypes.TEXT,
placeholder="something invalid dunno",
placeholder_expression=True,
)
self.assertEqual(
prompt.get_placeholder(context, self.user, self.factory.get("/")),
"something invalid dunno",
)
def test_prompt_placeholder_disabled(self):
"""Test placeholder and expression"""
context = {}
prompt: Prompt = Prompt(
field_key="text_prompt_expression",
label="TEXT_LABEL",
type=FieldTypes.TEXT,
placeholder="return prompt_context['foo']",
placeholder_expression=False,
)
self.assertEqual(
prompt.get_placeholder(context, self.user, self.factory.get("/")), prompt.placeholder
)
def test_field_types(self):
"""Ensure all field types can successfully be created"""
def test_invalid_save(self):
"""Ensure field can't be saved with invalid type"""
prompt: Prompt = Prompt(
field_key="text_prompt_expression",
label="TEXT_LABEL",
type="foo",
placeholder="foo",
placeholder_expression=False,
sub_text="test",
order=123,
)
with self.assertRaises(ValueError):
prompt.save()
def field_type_tester_factory(field_type: FieldTypes):
"""Test field for field_type"""
def tester(self: TestPromptStage):
prompt: Prompt = Prompt(
field_key="text_prompt_expression",
label="TEXT_LABEL",
type=field_type,
placeholder="foo",
placeholder_expression=False,
sub_text="test",
order=123,
)
self.assertIsNotNone(prompt.field("foo"))
return tester
for _type in FieldTypes:
setattr(TestPromptStage, f"test_field_type_{_type}", field_type_tester_factory(_type))

View File

@ -25,15 +25,16 @@ LOGGER = get_logger()
class UserWriteStageView(StageView):
"""Finalise Enrollment flow by creating a user object."""
def write_attribute(self, user: User, key: str, value: Any):
@staticmethod
def write_attribute(user: User, key: str, value: Any):
"""Allow use of attributes.foo.bar when writing to a user, with full
recursion"""
parts = key.replace("_", ".").split(".")
if len(parts) < 1: # pragma: no cover
return
# Function will always be called with a key like attribute.
# Function will always be called with a key like attributes.
# this is just a sanity check to ensure that is removed
if parts[0] == "attribute":
if parts[0] == "attributes":
parts = parts[1:]
attrs = user.attributes
for comp in parts[:-1]:
@ -84,16 +85,20 @@ class UserWriteStageView(StageView):
setter = getattr(user, setter_name)
if callable(setter):
setter(value)
# For exact attributes match, update the dictionary in place
elif key == "attributes":
user.attributes.update(value)
# User has this key already
elif hasattr(user, key):
elif hasattr(user, key) and not key.startswith("attributes."):
setattr(user, key, value)
# Otherwise we just save it as custom attribute, but only if the value is prefixed with
# `attribute_`, to prevent accidentally saving values
else:
if not key.startswith("attribute.") and not key.startswith("attribute_"):
if not key.startswith("attributes.") and not key.startswith("attributes_"):
LOGGER.debug("discarding key", key=key)
continue
self.write_attribute(user, key, value)
UserWriteStageView.write_attribute(user, key, value)
print(user.attributes)
# Extra check to prevent flows from saving a user with a blank username
if user.username == "":
LOGGER.warning("Aborting write to empty username", user=user)

View File

@ -16,6 +16,7 @@ from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
from authentik.stages.user_write.models import UserWriteStage
from authentik.stages.user_write.stage import UserWriteStageView
class TestUserWriteStage(FlowTestCase):
@ -77,7 +78,7 @@ class TestUserWriteStage(FlowTestCase):
plan.context[PLAN_CONTEXT_PROMPT] = {
"username": "test-user-new",
"password": new_password,
"attribute.some.custom-attribute": "test",
"attributes.some.custom-attribute": "test",
"some_ignored_attribute": "bar",
}
session = self.client.session
@ -172,3 +173,43 @@ class TestUserWriteStage(FlowTestCase):
self.flow,
component="ak-stage-access-denied",
)
def test_write_attribute(self):
"""Test write_attribute"""
user = create_test_admin_user()
user.attributes = {
"foo": "bar",
"baz": {
"qwer": [
"quox",
]
},
}
user.save()
UserWriteStageView.write_attribute(user, "attributes.foo", "baz")
self.assertEqual(
user.attributes,
{
"foo": "baz",
"baz": {
"qwer": [
"quox",
]
},
},
)
UserWriteStageView.write_attribute(user, "attributes.foob.bar", "baz")
self.assertEqual(
user.attributes,
{
"foo": "baz",
"foob": {
"bar": "baz",
},
"baz": {
"qwer": [
"quox",
]
},
},
)

View File

@ -50,6 +50,7 @@ class TenantSerializer(ModelSerializer):
"flow_invalidation",
"flow_recovery",
"flow_unenrollment",
"flow_user_settings",
"event_retention",
"web_certificate",
]
@ -72,6 +73,7 @@ class CurrentTenantSerializer(PassiveSerializer):
flow_invalidation = CharField(source="flow_invalidation.slug", required=False)
flow_recovery = CharField(source="flow_recovery.slug", required=False)
flow_unenrollment = CharField(source="flow_unenrollment.slug", required=False)
flow_user_settings = CharField(source="flow_user_settings.slug", required=False)
class TenantViewSet(UsedByMixin, ModelViewSet):

View File

@ -0,0 +1,181 @@
# Generated by Django 4.0.2 on 2022-02-26 21:14
import django.db.models.deletion
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from authentik.flows.models import FlowDesignation
from authentik.stages.identification.models import UserFields
from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP
AUTHORIZATION_POLICY = """from authentik.lib.config import CONFIG
from authentik.core.models import (
USER_ATTRIBUTE_CHANGE_EMAIL,
USER_ATTRIBUTE_CHANGE_NAME,
USER_ATTRIBUTE_CHANGE_USERNAME
)
prompt_data = request.context.get("prompt_data")
if not request.user.group_attributes().get(
USER_ATTRIBUTE_CHANGE_EMAIL, CONFIG.y_bool("default_user_change_email", True)
):
if prompt_data.get("email") != request.user.email:
ak_message("Not allowed to change email address.")
return False
if not request.user.group_attributes().get(
USER_ATTRIBUTE_CHANGE_NAME, CONFIG.y_bool("default_user_change_name", True)
):
if prompt_data.get("name") != request.user.name:
ak_message("Not allowed to change name.")
return False
if not request.user.group_attributes().get(
USER_ATTRIBUTE_CHANGE_USERNAME, CONFIG.y_bool("default_user_change_username", True)
):
if prompt_data.get("username") != request.user.username:
ak_message("Not allowed to change username.")
return False
return True
"""
def create_default_user_settings_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.stages.prompt.models import FieldTypes
db_alias = schema_editor.connection.alias
Tenant = apps.get_model("authentik_tenants", "Tenant")
Flow = apps.get_model("authentik_flows", "Flow")
FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")
ExpressionPolicy = apps.get_model("authentik_policies_expression", "ExpressionPolicy")
UserWriteStage = apps.get_model("authentik_stages_user_write", "UserWriteStage")
PromptStage = apps.get_model("authentik_stages_prompt", "PromptStage")
Prompt = apps.get_model("authentik_stages_prompt", "Prompt")
prompt_username, _ = Prompt.objects.using(db_alias).update_or_create(
field_key="username",
order=200,
defaults={
"label": "Username",
"type": FieldTypes.TEXT,
"placeholder": """try:
return user.username
except:
return ''""",
"placeholder_expression": True,
},
)
prompt_name, _ = Prompt.objects.using(db_alias).update_or_create(
field_key="name",
order=201,
defaults={
"label": "Name",
"type": FieldTypes.TEXT,
"placeholder": """try:
return user.name
except:
return ''""",
"placeholder_expression": True,
},
)
prompt_email, _ = Prompt.objects.using(db_alias).update_or_create(
field_key="email",
order=202,
defaults={
"label": "Email",
"type": FieldTypes.EMAIL,
"placeholder": """try:
return user.email
except:
return ''""",
"placeholder_expression": True,
},
)
prompt_locale, _ = Prompt.objects.using(db_alias).update_or_create(
field_key="attributes.settings.locale",
order=203,
defaults={
"label": "Locale",
"type": FieldTypes.AK_LOCALE,
"placeholder": """try:
return user.attributes.get("settings", {}).get("locale", "")
except:
return ''""",
"placeholder_expression": True,
"required": True,
},
)
validation_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create(
name="default-user-settings-authorization",
defaults={
"expression": AUTHORIZATION_POLICY,
},
)
prompt_stage, _ = PromptStage.objects.using(db_alias).update_or_create(
name="default-user-settings",
)
prompt_stage.validation_policies.set([validation_policy])
prompt_stage.fields.set([prompt_username, prompt_name, prompt_email, prompt_locale])
prompt_stage.save()
user_write, _ = UserWriteStage.objects.using(db_alias).update_or_create(
name="default-user-settings-write"
)
flow, _ = Flow.objects.using(db_alias).update_or_create(
slug="default-user-settings-flow",
designation=FlowDesignation.STAGE_CONFIGURATION,
defaults={
"name": "Update your info",
},
)
FlowStageBinding.objects.using(db_alias).update_or_create(
target=flow,
stage=prompt_stage,
defaults={
"order": 20,
},
)
FlowStageBinding.objects.using(db_alias).update_or_create(
target=flow,
stage=user_write,
defaults={
"order": 100,
},
)
tenant = Tenant.objects.using(db_alias).filter(default=True).first()
if not tenant:
return
tenant.flow_user_settings = flow
tenant.save()
class Migration(migrations.Migration):
dependencies = [
("authentik_policies_expression", "__latest__"),
("authentik_stages_prompt", "0007_prompt_placeholder_expression"),
("authentik_flows", "0021_auto_20211227_2103"),
("authentik_tenants", "0001_squashed_0005_tenant_web_certificate"),
]
operations = [
migrations.AddField(
model_name="tenant",
name="flow_user_settings",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="tenant_user_settings",
to="authentik_flows.flow",
),
),
migrations.RunPython(create_default_user_settings_flow),
]

View File

@ -40,6 +40,9 @@ class Tenant(models.Model):
flow_unenrollment = models.ForeignKey(
Flow, null=True, on_delete=models.SET_NULL, related_name="tenant_unenrollment"
)
flow_user_settings = models.ForeignKey(
Flow, null=True, on_delete=models.SET_NULL, related_name="tenant_user_settings"
)
event_retention = models.TextField(
default="days=365",

View File

@ -17,7 +17,7 @@ services:
image: redis:alpine
restart: unless-stopped
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.2.1}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.3.3}
restart: unless-stopped
command: server
environment:
@ -38,7 +38,7 @@ services:
- "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443"
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.2.1}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.3.3}
restart: unless-stopped
command: worker
environment:
@ -49,11 +49,10 @@ services:
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
# This is optional, and can be removed. If you remove this, the following will happen
# - The permissions for the /backups and /media folders aren't fixed, so make sure they are 1000:1000
# - The permissions for the /media folders aren't fixed, so make sure they are 1000:1000
# - The docker socket can't be accessed anymore
user: root
volumes:
- ./backups:/backups
- ./media:/media
- ./certs:/certs
- /var/run/docker.sock:/var/run/docker.sock

16
go.mod
View File

@ -4,12 +4,11 @@ go 1.16
require (
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/garyburd/redigo v1.6.2 // indirect
github.com/getsentry/sentry-go v0.12.0
github.com/getsentry/sentry-go v0.13.0
github.com/go-ldap/ldap/v3 v3.4.2
github.com/go-openapi/runtime v0.23.0
github.com/go-openapi/runtime v0.23.3
github.com/go-openapi/strfmt v0.21.2
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.3.0
@ -19,20 +18,21 @@ require (
github.com/gorilla/sessions v1.2.1
github.com/gorilla/websocket v1.5.0
github.com/imdario/mergo v0.3.12
github.com/mailru/easyjson v0.7.7 // indirect
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba
github.com/pires/go-proxyproto v0.6.1
github.com/pires/go-proxyproto v0.6.2
github.com/pkg/errors v0.9.1
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
github.com/prometheus/client_golang v1.12.1
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
goauthentik.io/api v0.2021125.1
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
github.com/stretchr/testify v1.7.1
goauthentik.io/api/v3 v3.2022032.1
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/yaml.v2 v2.4.0

216
go.sum
View File

@ -41,29 +41,21 @@ github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMd
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb h1:w9IDEB7P1VzNcBpOG7kMpFkZp2DkyJIUt0gDx5MBhRU=
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb/go.mod h1:9XMFaCeRyW7fC9XJOWQ+NdAv8VLG7ys7l3x4ozEGLUQ=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -91,7 +83,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
@ -100,7 +91,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -108,12 +98,10 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/garyburd/redigo v1.6.2 h1:yE/pwKCrbLpLpQICzYTeZ7JsTA/C53wFTJHaEtRqniM=
github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo=
github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
@ -131,108 +119,40 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ=
github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk=
github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
github.com/go-openapi/analysis v0.20.1 h1:zdVbw8yoD4SWZeq+cWdGgquaB0W4VrsJvDJHJND/Ktc=
github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
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.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU=
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
github.com/go-openapi/errors v0.19.8/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.1 h1:j23mMDtRxMwIobkpId7sWh7Ddcx4ivaoqUbfXx5P+a8=
github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8=
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY=
github.com/go-openapi/loads v0.19.6/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/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
github.com/go-openapi/loads v0.21.0 h1:jYtUO4wwP7psAweisP/MDoOpdzsYEESdoPcsWjHDR68=
github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws=
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.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.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.23.0 h1:HX6ET2sHCIvaKeDDQoU01CtO1ekg5EkekHSkLTtWXH0=
github.com/go-openapi/runtime v0.23.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/spec v0.19.15/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.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/loads v0.21.1 h1:Wb3nVZpdEzDTcly8S4HMkey6fjARRzb7iEaySimlDW0=
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
github.com/go-openapi/runtime v0.23.3 h1:/dxjx4KCOQI5ImBMz036F6v/DzZ2NUjSRvbLJs1rgoE=
github.com/go-openapi/runtime v0.23.3/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
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.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.4/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/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.2 h1:5NDNgadiX1Vhemth/TH4gCGopWSTdDjxl60H3B7f+os=
github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
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.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.7/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/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/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.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.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4=
github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI=
github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0=
github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw=
github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4=
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-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/validate v0.21.0 h1:+Wqk39yKOhfpLqNLEC0/eViCkzM5FVXVqrvt526+wcI=
github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@ -318,7 +238,6 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -340,7 +259,6 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
@ -351,8 +269,6 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
@ -367,7 +283,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
@ -375,10 +290,8 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
@ -388,18 +301,15 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
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=
@ -408,7 +318,6 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
@ -420,11 +329,10 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@ -446,19 +354,14 @@ github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba h1:DO8NFYdcRv1dnyAIN
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba/go.mod h1:4S0XndRL8HNOaQBfdViJ2F/GPCgL524xlXRuXFH12/U=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
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/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw=
github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8=
github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -517,16 +420,15 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
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/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
@ -536,12 +438,9 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@ -550,44 +449,33 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.3.0/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.4.3/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.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5 h1:ny3p0reEpgsR2cfA5cjgwFZg3Cv/ofFh/8jbhGtz9VI=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4=
go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
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.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
goauthentik.io/api v0.2021125.1 h1:Ja00N1D1wjqFiR90JV8nDayhmm39uLudzsJhwCjoQJ4=
goauthentik.io/api v0.2021125.1/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE=
goauthentik.io/api/v3 v3.2022032.1 h1:8PCy0tHUNjGVNJ7nuKPsK64vURFTeqUifyj68RlqMK4=
goauthentik.io/api/v3 v3.2022032.1/go.mod h1:QM9J32HgYE4gL71lWAfAoXSPdSmLVLW08itfLI3Mo10=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@ -623,14 +511,11 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -652,28 +537,26 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f h1:1scJEYZBaF48BaG6tYbtxmLcXqwYGSfGcMoStTqkkIw=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -688,13 +571,11 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cO
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -703,7 +584,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -729,7 +609,6 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/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-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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -741,15 +620,17 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
@ -759,10 +640,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@ -777,8 +656,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -890,8 +767,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b h1:U/Uqd1232+wrnHOvWNaxrNqn/kFnr4yu4blgPtQt0N8=
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b/go.mod h1:fgfIZMlsafAHpspcks2Bul+MWUNw/2dyQmjC2faKjtg=
@ -901,14 +779,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -25,4 +25,4 @@ func OutpostUserAgent() string {
return fmt.Sprintf("authentik-outpost@%s", FullVersion())
}
const VERSION = "2022.2.1"
const VERSION = "2022.3.3"

View File

@ -15,7 +15,7 @@ import (
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/constants"
log "github.com/sirupsen/logrus"

View File

@ -5,7 +5,7 @@ import (
"crypto/tls"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
)
type CryptoStore struct {

View File

@ -9,7 +9,7 @@ import (
"github.com/getsentry/sentry-go"
httptransport "github.com/go-openapi/runtime/client"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/constants"
)

View File

@ -10,7 +10,7 @@ import (
"github.com/google/uuid"
"github.com/gorilla/securecookie"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
)
func TestSecret() string {

View File

@ -14,7 +14,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/constants"
"goauthentik.io/internal/outpost/ak"
)

View File

@ -10,7 +10,7 @@ import (
"github.com/nmcclain/ldap"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/flow"
"goauthentik.io/internal/outpost/ldap/bind"
"goauthentik.io/internal/outpost/ldap/flags"

View File

@ -2,7 +2,7 @@ package ldap
import (
"github.com/nmcclain/ldap"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/utils"
)

View File

@ -1,6 +1,6 @@
package flags
import "goauthentik.io/api"
import "goauthentik.io/api/v3"
type UserFlags struct {
UserInfo *api.User

View File

@ -2,7 +2,7 @@ package group
import (
"github.com/nmcclain/ldap"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/server"
"goauthentik.io/internal/outpost/ldap/utils"

View File

@ -9,7 +9,7 @@ import (
"github.com/go-openapi/strfmt"
"github.com/nmcclain/ldap"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/constants"
"goauthentik.io/internal/outpost/ldap/bind"
ldapConstants "goauthentik.io/internal/outpost/ldap/constants"

View File

@ -9,7 +9,7 @@ import (
"github.com/go-openapi/strfmt"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
directbind "goauthentik.io/internal/outpost/ldap/bind/direct"
"goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/flags"

View File

@ -11,7 +11,7 @@ import (
"github.com/getsentry/sentry-go"
"github.com/nmcclain/ldap"
"github.com/prometheus/client_golang/prometheus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/group"
"goauthentik.io/internal/outpost/ldap/metrics"
@ -116,12 +116,12 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
var users *[]api.User
var groups *[]api.Group
errs, _ := errgroup.WithContext(req.Context())
errs, errCtx := errgroup.WithContext(req.Context())
if needUsers {
errs.Go(func() error {
if flags.CanSearch {
uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user")
uapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_user")
searchReq, skip := utils.ParseFilterForUser(c.CoreApi.CoreUsersList(uapisp.Context()), parsedFilter, false)
if skip {
@ -140,8 +140,8 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
users = &u.Results
} else {
if flags.UserInfo == nil {
uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user")
u, _, err := c.CoreApi.CoreUsersRetrieve(req.Context(), flags.UserPk).Execute()
uapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_user")
u, _, err := c.CoreApi.CoreUsersRetrieve(uapisp.Context(), flags.UserPk).Execute()
uapisp.Finish()
if err != nil {
@ -164,7 +164,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
if needGroups {
errs.Go(func() error {
gapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_group")
gapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_group")
searchReq, skip := utils.ParseFilterForGroup(c.CoreApi.CoreGroupsList(gapisp.Context()), parsedFilter, false)
if skip {
req.Log().Trace("Skip backend request")
@ -252,7 +252,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
if scope >= 0 && (strings.EqualFold(req.BaseDN, ds.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ds.si.GetBaseVirtualGroupDN())) {
singlevg := utils.HasSuffixNoCase(req.BaseDN, ","+ds.si.GetBaseVirtualGroupDN())
if !singlevg || utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) {
if !singlevg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) {
entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseVirtualGroupDN(), constants.OUVirtualGroups))
scope -= 1
}

View File

@ -3,7 +3,7 @@ package memory
import (
"context"
"goauthentik.io/api"
"goauthentik.io/api/v3"
)
const pageSize = 100

View File

@ -9,7 +9,7 @@ import (
"github.com/nmcclain/ldap"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/group"
"goauthentik.io/internal/outpost/ldap/metrics"

View File

@ -3,7 +3,7 @@ package server
import (
"github.com/go-openapi/strfmt"
"github.com/nmcclain/ldap"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/flags"
)

View File

@ -6,7 +6,7 @@ import (
"strconv"
"strings"
"goauthentik.io/api"
"goauthentik.io/api/v3"
)
func (pi *ProviderInstance) GroupsForUser(user api.User) []string {

View File

@ -51,7 +51,9 @@ func AKAttrsToLDAP(attrs interface{}) []*ldap.EntryAttribute {
entry.Values = make([]string, len(t))
for idx, v := range t {
v := ldapResolveTypeSingle(v)
entry.Values[idx] = *v
if v != nil {
entry.Values[idx] = *v
}
}
default:
v := ldapResolveTypeSingle(t)

View File

@ -6,7 +6,7 @@ import (
goldap "github.com/go-ldap/ldap/v3"
ber "github.com/nmcclain/asn1-ber"
"github.com/nmcclain/ldap"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
)

View File

@ -0,0 +1,72 @@
package utils
import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api/v3"
)
func TestAKAttrsToLDAP_String(t *testing.T) {
var d *map[string]interface{}
// normal string
d = &map[string]interface{}{
"foo": "bar",
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
assert.Equal(t, []string{"bar"}, AKAttrsToLDAP(d)[0].Values)
// pointer string
d = &map[string]interface{}{
"foo": api.PtrString("bar"),
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
assert.Equal(t, []string{"bar"}, AKAttrsToLDAP(d)[0].Values)
}
func TestAKAttrsToLDAP_String_List(t *testing.T) {
var d *map[string]interface{}
// string list
d = &map[string]interface{}{
"foo": []string{"bar"},
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
assert.Equal(t, []string{"bar"}, AKAttrsToLDAP(d)[0].Values)
// pointer string list
d = &map[string]interface{}{
"foo": &[]string{"bar"},
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
assert.Equal(t, []string{"bar"}, AKAttrsToLDAP(d)[0].Values)
}
func TestAKAttrsToLDAP_Dict(t *testing.T) {
// dict
d := &map[string]interface{}{
"foo": map[string]string{
"foo": "bar",
},
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
// Dicts are currently unsupported, but make sure we don't crash
// assert.Equal(t, []string{nil}, AKAttrsToLDAP(d)[0].Values)
}
func TestAKAttrsToLDAP_Mixed(t *testing.T) {
// dict
d := &map[string]interface{}{
"foo": []interface{}{
"foo",
6,
},
}
assert.Equal(t, 1, len(AKAttrsToLDAP(d)))
assert.Equal(t, "foo", AKAttrsToLDAP(d)[0].Name)
// Dicts are currently unsupported, but make sure we don't crash
// assert.Equal(t, []string{nil}, AKAttrsToLDAP(d)[0].Values)
}

View File

@ -4,7 +4,7 @@ import (
goldap "github.com/go-ldap/ldap/v3"
ber "github.com/nmcclain/asn1-ber"
"github.com/nmcclain/ldap"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/constants"
)

View File

@ -20,7 +20,7 @@ import (
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ak"
"goauthentik.io/internal/outpost/proxyv2/constants"
"goauthentik.io/internal/outpost/proxyv2/hs256"

View File

@ -6,7 +6,7 @@ import (
"strings"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"golang.org/x/oauth2"
)

View File

@ -9,7 +9,7 @@ import (
"net/url"
"strings"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/constants"
)
@ -123,8 +123,9 @@ func (a *Application) IsAllowlisted(u *url.URL) bool {
} else {
testString = u.String()
}
a.log.WithField("regex", u.String()).WithField("url", testString).Trace("Matching URL against allow list")
if ur.MatchString(testString) {
match := ur.MatchString(testString)
a.log.WithField("match", match).WithField("regex", ur.String()).WithField("url", testString).Trace("Matching URL against allow list")
if match {
return true
}
}

View File

@ -0,0 +1,50 @@
package application
import (
"net/url"
"regexp"
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api/v3"
)
func urlMustParse(u string) *url.URL {
ur, err := url.Parse(u)
if err != nil {
panic(err)
}
return ur
}
func TestIsAllowlisted_Proxy_Single(t *testing.T) {
a := newTestApplication()
a.proxyConfig.Mode = api.PROXYMODE_PROXY.Ptr()
assert.Equal(t, false, a.IsAllowlisted(urlMustParse("")))
a.UnauthenticatedRegex = []*regexp.Regexp{
regexp.MustCompile("^/foo"),
}
assert.Equal(t, true, a.IsAllowlisted(urlMustParse("http://some-host/foo")))
}
func TestIsAllowlisted_Proxy_Domain(t *testing.T) {
a := newTestApplication()
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
assert.Equal(t, false, a.IsAllowlisted(urlMustParse("")))
a.UnauthenticatedRegex = []*regexp.Regexp{
regexp.MustCompile("^/foo"),
}
assert.Equal(t, false, a.IsAllowlisted(urlMustParse("http://some-host/foo")))
a.UnauthenticatedRegex = []*regexp.Regexp{
regexp.MustCompile("^http://some-host/foo"),
}
assert.Equal(t, true, a.IsAllowlisted(urlMustParse("http://some-host/foo")))
a.UnauthenticatedRegex = []*regexp.Regexp{
regexp.MustCompile("https://health.domain.tld/ping/*"),
}
assert.Equal(t, false, a.IsAllowlisted(urlMustParse("http://some-host/foo")))
assert.Equal(t, false, a.IsAllowlisted(urlMustParse("https://health.domain.tld/")))
assert.Equal(t, true, a.IsAllowlisted(urlMustParse("https://health.domain.tld/ping/qq")))
}

View File

@ -6,7 +6,7 @@ import (
"net/url"
"strings"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
"goauthentik.io/internal/utils/web"
)

View File

@ -6,7 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
)

View File

@ -6,7 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
)

View File

@ -8,7 +8,7 @@ import (
"time"
"github.com/gorilla/securecookie"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
)

View File

@ -5,7 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api"
"goauthentik.io/api/v3"
)
func TestCheckRedirectParam(t *testing.T) {
@ -24,12 +24,12 @@ func TestCheckRedirectParam(t *testing.T) {
assert.Equal(t, false, ok)
assert.Equal(t, "", rd)
req, _ = http.NewRequest("GET", "/outpost.goauthentik.io/auth/start?rd=https://ext.t.goauthentik.io/test", nil)
req, _ = http.NewRequest("GET", "/outpost.goauthentik.io/auth/start?rd=https://ext.t.goauthentik.io/test?foo", nil)
rd, ok = a.checkRedirectParam(req)
assert.Equal(t, true, ok)
assert.Equal(t, "https://ext.t.goauthentik.io/test", rd)
assert.Equal(t, "https://ext.t.goauthentik.io/test?foo", rd)
}
func TestCheckRedirectParam_Domain(t *testing.T) {

View File

@ -7,7 +7,7 @@ import (
"strconv"
"github.com/gorilla/sessions"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/config"
"gopkg.in/boj/redistore.v1"
)
@ -28,7 +28,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig) sessions.Store {
rs.SetMaxAge(0)
}
rs.Options.Domain = *p.CookieDomain
a.log.Info("using redis session backend")
a.log.Debug("using redis session backend")
store = rs
} else {
dir := os.TempDir()
@ -48,7 +48,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig) sessions.Store {
cs.MaxAge(0)
}
cs.Options.Domain = *p.CookieDomain
a.log.WithField("dir", dir).Info("using filesystem session backend")
a.log.WithField("dir", dir).Debug("using filesystem session backend")
store = cs
}
return store

View File

@ -4,7 +4,7 @@ import (
"net/http"
"github.com/quasoft/memstore"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ak"
)

View File

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
)
@ -23,7 +23,7 @@ func urlJoin(originalUrl string, newPath string) string {
func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) {
s, err := a.sessions.Get(r, constants.SeesionName)
if err == nil {
if err != nil {
a.log.WithError(err).Warning("failed to decode session")
}
redirectUrl := urlJoin(a.proxyConfig.ExternalHost, r.URL.Path)
@ -42,8 +42,11 @@ func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) {
a.log.WithError(err).Warning("failed to save session before redirect")
}
urlArgs := url.Values{
"rd": []string{redirectUrl},
}
authUrl := urlJoin(a.proxyConfig.ExternalHost, "/outpost.goauthentik.io/start")
http.Redirect(rw, r, authUrl, http.StatusFound)
http.Redirect(rw, r, authUrl+"?"+urlArgs.Encode(), http.StatusFound)
}
// getClaims Get claims which are currently in session

View File

@ -6,7 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/constants"
)
@ -21,7 +21,7 @@ func TestRedirectToStart_Proxy(t *testing.T) {
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start", loc.String())
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start?rd=https%3A%2F%2Ftest.goauthentik.io%2Ffoo%2Fbar%2Fbaz", loc.String())
s, _ := a.sessions.Get(req, constants.SeesionName)
assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect])
@ -38,7 +38,7 @@ func TestRedirectToStart_Forward(t *testing.T) {
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start", loc.String())
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start?rd=https%3A%2F%2Ftest.goauthentik.io%2Ffoo%2Fbar%2Fbaz", loc.String())
s, _ := a.sessions.Get(req, constants.SeesionName)
assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect])
@ -56,7 +56,7 @@ func TestRedirectToStart_Forward_Domain_Invalid(t *testing.T) {
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start", loc.String())
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start?rd=https%3A%2F%2Ftest.goauthentik.io", loc.String())
s, _ := a.sessions.Get(req, constants.SeesionName)
assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect])
@ -74,7 +74,7 @@ func TestRedirectToStart_Forward_Domain(t *testing.T) {
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start", loc.String())
assert.Equal(t, "https://test.goauthentik.io/outpost.goauthentik.io/start?rd=https%3A%2F%2Ftest.goauthentik.io", loc.String())
s, _ := a.sessions.Get(req, constants.SeesionName)
assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect])

View File

@ -8,7 +8,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
"goauthentik.io/api"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/proxyv2/application"
"goauthentik.io/internal/outpost/proxyv2/metrics"
"goauthentik.io/internal/utils/web"

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