Compare commits

..

253 Commits

Author SHA1 Message Date
24eb4ed963 release: 2022.12.0 2022-12-28 13:00:49 +01:00
0e6400bfea web/admin: improve user/group UX for adding/removing users to and from groups
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-28 12:55:38 +01:00
be308b3392 web/admin: lint
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-28 12:07:14 +01:00
62aa4336a8 web: bump API Client version (#4294)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-28 11:02:02 +01:00
b16d1134ea core: add endpoints to add/remove users from group atomically
closes #4252

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-28 10:50:30 +01:00
78f7eb4345 web/elements: fix wizard form page changing state before being active
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-27 20:21:58 +01:00
1615723f10 website/docs: update release notes for 2022.12
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-27 14:10:38 +01:00
sev
f9b46145de website/docs: Clarify request.user and add link to Django docs (#4287)
* Clarify request.user and add link to doc

Signed-off-by: sev <git@sev.monster>

* rephrase a bit

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

Signed-off-by: sev <git@sev.monster>
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-27 14:10:30 +01:00
20a4dfd13d stages/invitation: fix incorrect pk check for invitation's flow
closes #4278

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-27 13:55:51 +01:00
4a6f8d2ef2 web/flows: update flow background
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-27 13:47:16 +01:00
ffdc1aa9c2 web: bump @typescript-eslint/eslint-plugin from 5.47.0 to 5.47.1 in /web (#4290)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.47.0 to 5.47.1.
- [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.47.1/packages/eslint-plugin)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-27 09:43:32 +01:00
138801c18b web: bump @typescript-eslint/parser from 5.47.0 to 5.47.1 in /web (#4291)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.47.0 to 5.47.1.
- [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.47.1/packages/parser)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-27 09:42:15 +01:00
8f3579ba45 blueprints: add !If tag (#4264)
* Added \!If tag

* Fix typo

* Removed trailing whitespace

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* format blueprint fixtures

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

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-26 16:20:22 +01:00
3eecc76717 web/admin: fix linting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-26 15:35:08 +01:00
0488d36257 web: bump @codemirror/lang-python from 6.1.0 to 6.1.1 in /web (#4284) 2022-12-26 12:57:54 +01:00
340bf54315 core: bump goauthentik.io/api/v3 from 3.2022113.3 to 3.2022114.2 (#4285) 2022-12-26 12:57:43 +01:00
b33f3d9cc8 core: bump coverage from 7.0.0 to 7.0.1 (#4286) 2022-12-26 12:57:21 +01:00
dbaf03430e web/admin: show stage binding form when creating stage in bound list
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 15:09:22 +01:00
f5738804ff web: bump API Client version (#4282)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-25 15:00:55 +01:00
bfa0360764 web/admin: show policy binding form when creating policy in bound list
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 14:59:45 +01:00
ae13fc3b92 policies: make name required
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 14:46:48 +01:00
7046944bf6 website: link CVE and attribute reporter
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 14:17:17 +01:00
0423023d2e web/elements: fix table select-all checkbox being checked with no elements
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 14:10:02 +01:00
5132f0f876 web/admin: more consistent label usage, use compact labels
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 14:06:29 +01:00
7e44de2da9 web: ignore d3 circular deps warning, treat unresolved import as error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 13:44:09 +01:00
08b0075335 web/admin: fix import error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-25 13:18:56 +01:00
efbab9e37f web: remove @types/mermaid
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-24 22:32:21 +01:00
8195e6d4ff website/integrations: add hcp docs (#4281)
add hcp docs

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-24 22:27:33 +01:00
700a4cb72c web/admin: fix application to provider links
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-24 21:55:29 +01:00
94b9ebb0bb blueprints: add Env tag
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-24 20:41:51 +01:00
fe1e2aa8af website: fix missing integrations in sidebar
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-24 00:50:12 +01:00
7835f3d873 root: update supported versions
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 16:08:50 +01:00
4a50c65cad web: bump API Client version (#4277)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-23 15:30:38 +01:00
283c93c57b website: copy static files instead of linking them to prevent cache issues
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 15:18:21 +01:00
1b86a3d5d6 Merge branch 'version-2022.11' 2022-12-23 14:39:52 +01:00
8b710b57a5 root: don't send traces in testing
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:37:58 +01:00
716584bbae website: update release notes for CVEs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:21:02 +01:00
9dc0bb2a77 release: 2022.11.4 2022-12-23 14:17:48 +01:00
debbcb125b web: backport API update
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:17:32 +01:00
2d827eaae1 security: fix CVE 2022 23555 (#4274)
* add flow to invitation

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

* show warning on invitation page

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

* add security advisory

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

* add tests

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:16:30 +01:00
47d79ac28c security: fix CVE 2022 46172 (#4275)
* fallback to current user in user_write, add flag to disable user creation

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

* update api and web ui

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

* update default flows

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

* add cve post to website

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

* add tests

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:16:26 +01:00
61f2b73255 web: bump API Client version (#4276)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-23 14:15:57 +01:00
9f846d94be security: fix CVE 2022 23555 (#4274)
* add flow to invitation

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

* show warning on invitation page

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

* add security advisory

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

* add tests

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:13:49 +01:00
84fbeb5721 security: fix CVE 2022 46172 (#4275)
* fallback to current user in user_write, add flag to disable user creation

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

* update api and web ui

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

* update default flows

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

* add cve post to website

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

* add tests

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 14:12:58 +01:00
01da8e1792 providers/oauth2: optimise and cache signing key, prevent key being loaded multiple times
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 12:04:31 +01:00
6a3a3e5f8d website: fix duplicate platforms in sidebar
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 11:23:41 +01:00
42c278b4f8 root: migrate to hosted sentry with rate-limited DSN
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-23 11:18:26 +01:00
e49bc83266 web: bump @sentry/browser from 7.28.0 to 7.28.1 in /web (#4267)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.28.0 to 7.28.1.
- [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/7.28.0...7.28.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-23 10:29:03 +01:00
98b7ebec74 web: bump @sentry/tracing from 7.28.0 to 7.28.1 in /web (#4268)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.28.0 to 7.28.1.
- [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/7.28.0...7.28.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-23 10:26:45 +01:00
ccb43a3dfb web: bump @babel/plugin-proposal-decorators from 7.20.5 to 7.20.7 in /web (#4270)
web: bump @babel/plugin-proposal-decorators in /web

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-23 10:26:32 +01:00
c92b2620f5 web: bump @babel/core from 7.20.5 to 7.20.7 in /web (#4269)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.20.5 to 7.20.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.7/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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-23 10:25:20 +01:00
e2bfeefc8b core: bump dacite from 1.6.0 to 1.7.0 (#4271)
Bumps [dacite](https://github.com/konradhalas/dacite) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/konradhalas/dacite/releases)
- [Changelog](https://github.com/konradhalas/dacite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/konradhalas/dacite/compare/v1.6.0...v1.7.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-23 10:19:57 +01:00
e52c964354 flows: fix redirect from plan context "redirect" not being wrapped in flow response
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 23:28:26 +01:00
c635487210 blueprints: better OCI support in UI (#4263)
use oci:// prefix to detect oci blueprint, add UI support

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 18:49:25 +01:00
ca6cd8a4d3 website/developer-docs: update release procedure to include CVEs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 18:07:59 +01:00
fb09df26c9 core: fix lint
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 17:56:05 +01:00
30f4a09a88 web/elements: fix alignment for checkboxes in table
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 17:31:06 +01:00
7143ea08e6 web/admin: improve i18n for documentation link in outpost form
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 17:30:54 +01:00
e4e7a112e3 web: use version family subdomain for in-app doc links
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 17:03:08 +01:00
4c133b957c web/user: fix styling for clear all button in notification drawer
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 16:37:49 +01:00
28eb7c03fa website/developer-docs: add templates for announcing fixed security release
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 16:13:21 +01:00
7b01a208a2 web/elements: unselect top checkbox in table when not all elements are selected
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 16:02:04 +01:00
db0af3763b web/elements: fix alignment with checkbox in table
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 15:12:47 +01:00
ab9efcea77 web/elements: fix log level for diagram
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 15:12:30 +01:00
d280577830 website: migrate to hosted plausible
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 14:47:49 +01:00
36da29aaa2 website/developer-docs: add release procedure
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 12:01:34 +01:00
9e1204b645 root: add security mailing list
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-22 11:14:03 +01:00
ea2f69a8f8 web: bump yaml from 2.1.3 to 2.2.0 in /web (#4258)
Bumps [yaml](https://github.com/eemeli/yaml) from 2.1.3 to 2.2.0.
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v2.1.3...v2.2.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-22 11:01:29 +01:00
55a705e777 web: bump pyright from 1.1.284 to 1.1.285 in /web (#4259)
Bumps [pyright](https://github.com/Microsoft/pyright/tree/HEAD/packages/pyright) from 1.1.284 to 1.1.285.
- [Release notes](https://github.com/Microsoft/pyright/releases)
- [Commits](https://github.com/Microsoft/pyright/commits/1.1.285/packages/pyright)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-22 11:01:20 +01:00
cb10289b68 core: bump goauthentik.io/api/v3 from 3.2022113.2 to 3.2022113.3 (#4260)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022113.2 to 3.2022113.3.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022113.2...v3.2022113.3)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-22 11:01:10 +01:00
423776c7a2 website/docs: prepare 2022.12 release
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 21:58:57 +01:00
e5cfddfc57 web: fix linting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 20:25:42 +01:00
1564b898db web/admin: fix alignment in tables with multiple elements in cell
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 20:06:36 +01:00
3b61c6f9b9 web/admin: improve UI for removing users from groups and groups from users
no longer deletes users/groups when they are removed from the opposite

closes #4251 closes #3964

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 19:16:00 +01:00
042865c606 blueprints: add conditions to blueprint schema
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 18:59:17 +01:00
7f662ac2f3 blueprints: Added conditional entry application (#4167)
* blueprints: Added !AsBool tag

* Renamed AsBool tag to Condition

* Added conditions attributed to BlueprintEntry

* Added docs for the conditions attribute of a blueprint entry

* Website linting fix

* add new tag to vscode settings

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 17:04:00 +00:00
e9f5d7aefe web: bump API Client version (#4257)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-21 12:15:29 +01:00
609f95ac97 providers: add preview for mappings (#4254)
* preview

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

* web/admin: show provider page on application page

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

* use oauth2 end session url instead of direct interface

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

* dont show provider page on application page for now

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

* add UI for preview

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

* translate and release notes

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

* fix lint

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

* separate saml api files

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

* add api tests

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-21 12:13:11 +01:00
0181a90d98 web: bump @sentry/tracing from 7.27.0 to 7.28.0 in /web (#4255)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.27.0 to 7.28.0.
- [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/7.27.0...7.28.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-21 10:25:21 +01:00
243f335718 web: bump @sentry/browser from 7.27.0 to 7.28.0 in /web (#4256)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.27.0 to 7.28.0.
- [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/7.27.0...7.28.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-21 10:23:17 +01:00
f4990bb5da core: bundle geoip (#4250)
* bundle geoip

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

* correctly pass secrets

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

* add geoip docs and release notes

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-20 22:09:30 +01:00
980d2a022c web/admin: show bound policies order first to match stages
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-20 14:59:17 +01:00
81fdd097c6 website/integrations: add note for nextcloud index.php (#4210)
* feat(docs/nextcloud): Updated docs

It was missing the proper syntax for urls with index.php in between.

* feat(docs/nextcloud): Address PR suggestion

* fix formatting, use identical casing for nextcloud

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-20 11:12:15 +01:00
2b4c9657a6 web: bump @typescript-eslint/eslint-plugin from 5.46.1 to 5.47.0 in /web (#4245)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.46.1 to 5.47.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.47.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-20 10:14:30 +01:00
45d30213b3 web: bump @typescript-eslint/parser from 5.46.1 to 5.47.0 in /web (#4246)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.46.1 to 5.47.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.47.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-20 10:07:15 +01:00
7884ff07bb core: bump sentry-sdk from 1.12.0 to 1.12.1 (#4247)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.12.0 to 1.12.1.
- [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.12.0...1.12.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-20 10:07:02 +01:00
bacf2afed1 internal: remove sentry proxy
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 17:52:07 +01:00
67b45fc4e3 web/admin: break all in code blocks in event info
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 13:00:55 +01:00
c28f3ab225 web/elements: fix flaky formatting
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 12:58:22 +01:00
027ca88d83 lib: enable sentry profiles_sample_rate
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 12:51:22 +01:00
9d5b9204fc web/admin: rework markdown, correctly render Admonitions, fix links
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 12:48:02 +01:00
39e0ed2962 web/admin: better show metadata download for saml provider
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 10:54:51 +01:00
3b973e12a4 blueprints: don't require auth on invalidation flow
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-19 10:33:54 +01:00
d80573bdc5 web: bump @sentry/tracing from 7.26.0 to 7.27.0 in /web (#4231)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.26.0 to 7.27.0.
- [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/7.26.0...7.27.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:16:56 +01:00
4182bfd8b5 website/integrations: fix typo (#4228)
Signed-off-by: jonah <73760377+jonerrr@users.noreply.github.com>

Signed-off-by: jonah <73760377+jonerrr@users.noreply.github.com>
2022-12-19 10:15:19 +01:00
07a5b49454 web: bump eslint-plugin-lit from 1.7.1 to 1.7.2 in /web (#4234)
Bumps [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) from 1.7.1 to 1.7.2.
- [Release notes](https://github.com/43081j/eslint-plugin-lit/releases)
- [Commits](https://github.com/43081j/eslint-plugin-lit/compare/v1.7.1...v1.7.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-lit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:14:31 +01:00
16be699190 web: bump @rollup/plugin-replace from 5.0.1 to 5.0.2 in /web (#4235)
Bumps [@rollup/plugin-replace](https://github.com/rollup/plugins/tree/HEAD/packages/replace) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/replace/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/json-v5.0.2/packages/replace)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:13:06 +01:00
e523dd188c web: bump eslint from 8.29.0 to 8.30.0 in /web (#4232)
Bumps [eslint](https://github.com/eslint/eslint) from 8.29.0 to 8.30.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.29.0...v8.30.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:12:53 +01:00
73a2682ed6 core: bump goauthentik.io/api/v3 from 3.2022113.1 to 3.2022113.2 (#4238)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022113.1 to 3.2022113.2.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022113.1...v3.2022113.2)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:11:59 +01:00
3d9f8c80a5 web: bump @sentry/browser from 7.26.0 to 7.27.0 in /web (#4237)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.26.0 to 7.27.0.
- [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/7.26.0...7.27.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:11:49 +01:00
754061dba5 web: bump @patternfly/patternfly from 4.221.2 to 4.222.4 in /web (#4233)
Bumps [@patternfly/patternfly](https://github.com/patternfly/patternfly) from 4.221.2 to 4.222.4.
- [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.221.2...prerelease-v4.222.4)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:11:17 +01:00
48c520150f web: bump chart.js from 4.0.1 to 4.1.1 in /web (#4236)
Bumps [chart.js](https://github.com/chartjs/Chart.js) from 4.0.1 to 4.1.1.
- [Release notes](https://github.com/chartjs/Chart.js/releases)
- [Commits](https://github.com/chartjs/Chart.js/compare/v4.0.1...v4.1.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:10:59 +01:00
a754196a48 web: bump @rollup/plugin-commonjs from 23.0.5 to 24.0.0 in /web (#4239)
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 23.0.5 to 24.0.0.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/commonjs-v24.0.0/packages/commonjs)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:10:38 +01:00
23fce4e74d core: bump importlib-metadata from 5.1.0 to 5.2.0 (#4240)
Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 5.1.0 to 5.2.0.
- [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/v5.1.0...v5.2.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:10:26 +01:00
ab05abe787 core: bump coverage from 6.5.0 to 7.0.0 (#4241)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 6.5.0 to 7.0.0.
- [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.5.0...7.0.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:10:16 +01:00
67c8febb33 core: bump drf-spectacular from 0.25.0 to 0.25.1 (#4242)
Bumps [drf-spectacular](https://github.com/tfranzel/drf-spectacular) from 0.25.0 to 0.25.1.
- [Release notes](https://github.com/tfranzel/drf-spectacular/releases)
- [Changelog](https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tfranzel/drf-spectacular/compare/0.25.0...0.25.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:08:08 +01:00
5d397716de core: bump pylint from 2.15.8 to 2.15.9 (#4243)
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.15.8 to 2.15.9.
- [Release notes](https://github.com/PyCQA/pylint/releases)
- [Commits](https://github.com/PyCQA/pylint/compare/v2.15.8...v2.15.9)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-19 10:04:33 +01:00
5a7c46b3ef web: bump API Client version (#4229)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-18 14:21:09 +01:00
ec925491b2 stages/captcha: customisable URLs (#3832)
* make api and js url customisable

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

* use recaptcha.net domains

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

* add form

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

* regen locale

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-18 14:18:43 +01:00
2d18c1bb6f root: Update badge URLs (#4226)
https://github.com/badges/shields/issues/8671

Signed-off-by: Issy Szemeti <48881813+issy@users.noreply.github.com>

Signed-off-by: Issy Szemeti <48881813+issy@users.noreply.github.com>
2022-12-16 21:22:33 +01:00
2aba32de19 core: bump sentry-sdk from 1.11.1 to 1.12.0 (#4224)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.11.1 to 1.12.0.
- [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.11.1...1.12.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 11:09:32 +01:00
a13dc847f0 web: bump mermaid from 9.2.2 to 9.3.0 in /web (#4223)
Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 9.2.2 to 9.3.0.
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Changelog](https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/mermaid-js/mermaid/compare/v9.2.2...v9.3.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 11:09:22 +01:00
d66670f6ac web: bump @rollup/plugin-commonjs from 23.0.4 to 23.0.5 in /web (#4222)
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 23.0.4 to 23.0.5.
- [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-v23.0.5/packages/commonjs)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 11:09:07 +01:00
3418943949 root: allow custom settings via python module
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-15 10:59:14 +01:00
f5c89f68a4 core: bump twilio from 7.15.4 to 7.16.0 (#4219)
Bumps [twilio](https://github.com/twilio/twilio-python) from 7.15.4 to 7.16.0.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/7.15.4...7.16.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 10:08:48 +01:00
8fc942fbf4 web: bump @sentry/browser from 7.25.0 to 7.26.0 in /web (#4211)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.25.0 to 7.26.0.
- [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/7.25.0...7.26.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:52:36 +01:00
83d2c8fc33 ci: bump helm/kind-action from 1.4.0 to 1.5.0 (#4212)
Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](https://github.com/helm/kind-action/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: helm/kind-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:46:57 +01:00
89839096ee web: bump pyright from 1.1.282 to 1.1.284 in /web (#4213)
Bumps [pyright](https://github.com/Microsoft/pyright/tree/HEAD/packages/pyright) from 1.1.282 to 1.1.284.
- [Release notes](https://github.com/Microsoft/pyright/releases)
- [Commits](https://github.com/Microsoft/pyright/commits/1.1.284/packages/pyright)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:46:38 +01:00
a08d4bc720 web: bump @sentry/tracing from 7.25.0 to 7.26.0 in /web (#4214)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.25.0 to 7.26.0.
- [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/7.25.0...7.26.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:46:21 +01:00
7674ef3950 core: bump lxml from 4.9.1 to 4.9.2 (#4215)
Bumps [lxml](https://github.com/lxml/lxml) from 4.9.1 to 4.9.2.
- [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.9.1...lxml-4.9.2)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:45:46 +01:00
72c474f3b1 core: bump drf-spectacular from 0.24.2 to 0.25.0 (#4216)
Bumps [drf-spectacular](https://github.com/tfranzel/drf-spectacular) from 0.24.2 to 0.25.0.
- [Release notes](https://github.com/tfranzel/drf-spectacular/releases)
- [Changelog](https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tfranzel/drf-spectacular/compare/0.24.2...0.25.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-14 14:45:38 +01:00
1dfc0b2e93 website/docs: update flow context variables
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-13 14:37:37 +00:00
291573fbc5 website/integrations: Add docs for Skyhigh (#3890)
* Add Skyhigh Security documentation

* Add Skyhigh to infrastructure application menu

* Add Skyhigh to infrastructure application menu

* fix linting

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-13 12:21:13 +01:00
0995658ca6 website/docs: add note for possibly blocked SMTP ports
closes #4192

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-13 11:13:52 +00:00
53f3764879 website/integrations: update/extend Gitea integration (#3946)
* website/docs: update/extend gitea integration

* website/docs: update/extend gitea integration / run prettier

* website/integrations: update/extend Gitea integration / switched to database based filtering

Co-authored-by: NWHirschfeld <git@nwhirschfeld.de>
2022-12-13 12:02:49 +01:00
bdd8b59ab9 website/integrations: Update Wiki.JS documentation (#4146)
* Update Wiki.JS documentation

updated based on UI changes in latest Authentik version

under providers, removed settings that are now the default. default Subject Mode also works instead of changing to based on username.

under self registration note, updated to reflect that emails must match instead of usernames, tested with latest wikijs and authentik

* fix lint

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-13 11:56:48 +01:00
c3a8e35a2f core: bump goauthentik.io/api/v3 from 3.2022112.1 to 3.2022113.1 (#4205)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022112.1 to 3.2022113.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022112.1...v3.2022113.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:44:05 +01:00
c979be6e25 web: bump @typescript-eslint/parser from 5.46.0 to 5.46.1 in /web (#4204)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.46.0 to 5.46.1.
- [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.46.1/packages/parser)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:43:18 +01:00
b7092cc307 web: bump @sentry/browser from 7.24.2 to 7.25.0 in /web (#4203)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.24.2 to 7.25.0.
- [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/7.24.2...7.25.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:42:41 +01:00
3aa262efbe web: bump @sentry/tracing from 7.24.2 to 7.25.0 in /web (#4202)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.24.2 to 7.25.0.
- [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/7.24.2...7.25.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:41:19 +01:00
3cc326bca8 web: bump @typescript-eslint/eslint-plugin from 5.46.0 to 5.46.1 in /web (#4201)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.46.0 to 5.46.1.
- [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.46.1/packages/eslint-plugin)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:41:09 +01:00
168c34f172 web: bump eslint-plugin-lit from 1.7.0 to 1.7.1 in /web (#4206)
Bumps [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/43081j/eslint-plugin-lit/releases)
- [Commits](https://github.com/43081j/eslint-plugin-lit/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-lit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 11:40:59 +01:00
b3da1d223c providers/proxy: correctly set id_token_hint if possible
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 19:02:37 +00:00
107f2745c8 providers/ldap: improve mapping of LDAP filters to authentik queries
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 18:30:52 +00:00
6f9002eb01 web: bump API Client version (#4200)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-12 18:09:45 +01:00
12db0637ec lifecycle: improve explanation for user: root and docket socket mount
closes #2779

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 17:06:26 +00:00
8d169a8bd9 Merge branch 'version-2022.11' 2022-12-12 17:05:39 +00:00
f47ce9a360 stages/user_login: prevent double success message when logging in via source
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 16:34:16 +00:00
4816b90378 root: update locales
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 16:23:30 +00:00
01a897dbc2 flows: set stage name and verbose_name for in_memory stages
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 16:22:48 +00:00
45eb8baee8 web/admin: fix action button order for blueprints
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 16:22:33 +00:00
4bf6cfc4d8 website/integrations: fix instruction links on source pages (#4196)
* website/integrations: fix links for adding source to login page instructions

* website/integrations: add missing login page instruction link to plex

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 15:54:21 +00:00
fddcb3a835 events: remove legacy logger declaration
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 15:32:06 +00:00
5d51621278 stages/user_write: always ignore component field and prevent warning
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 15:31:56 +00:00
9ffc720f48 policies: log correct cache state
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 15:31:41 +00:00
b6b72e389d internal: dont error if environment config isn't found
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-12 10:38:38 +00:00
5ae593bc00 website/docs: Fix typo in ldap source documentation (#4197)
Signed-off-by: Nils K <24257556+septatrix@users.noreply.github.com>

Signed-off-by: Nils K <24257556+septatrix@users.noreply.github.com>
2022-12-12 11:33:32 +01:00
44fe477c3c website: bump postcss from 8.4.19 to 8.4.20 in /website (#4198)
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.19 to 8.4.20.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.19...8.4.20)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-12 11:15:20 +01:00
43bc60610d core: bump black from 22.10.0 to 22.12.0 (#4199)
Bumps [black](https://github.com/psf/black) from 22.10.0 to 22.12.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.10.0...22.12.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-12 11:14:39 +01:00
c21c1757de core: bump github.com/getsentry/sentry-go from 0.15.0 to 0.16.0 (#4179)
* core: bump github.com/getsentry/sentry-go from 0.15.0 to 0.16.0

Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.15.0 to 0.16.0.
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: github.com/getsentry/sentry-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* update custom tracer

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

Signed-off-by: dependabot[bot] <support@github.com>
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-12-09 12:20:41 +01:00
d3197f3430 web: bump @sentry/tracing from 7.23.0 to 7.24.2 in /web (#4176)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.23.0 to 7.24.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/7.23.0...7.24.2)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:08:04 +01:00
3d23770e9d web: bump @codemirror/lang-javascript from 6.1.1 to 6.1.2 in /web (#4173)
Bumps [@codemirror/lang-javascript](https://github.com/codemirror/lang-javascript) from 6.1.1 to 6.1.2.
- [Release notes](https://github.com/codemirror/lang-javascript/releases)
- [Changelog](https://github.com/codemirror/lang-javascript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-javascript/compare/6.1.1...6.1.2)

---
updated-dependencies:
- dependency-name: "@codemirror/lang-javascript"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:07:50 +01:00
0fc0a62279 web: bump @rollup/plugin-commonjs from 23.0.3 to 23.0.4 in /web (#4177)
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 23.0.3 to 23.0.4.
- [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-v23.0.4/packages/commonjs)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:07:40 +01:00
4da370b458 web: bump @typescript-eslint/parser from 5.45.1 to 5.46.0 in /web (#4186)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.45.1 to 5.46.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.46.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:07:27 +01:00
aa3e085536 web: bump @sentry/browser from 7.23.0 to 7.24.2 in /web (#4174)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.23.0 to 7.24.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/7.23.0...7.24.2)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:06:18 +01:00
253b676f7d website: bump prettier from 2.8.0 to 2.8.1 in /website (#4172)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:06:07 +01:00
9f4f911fd3 web: bump prettier from 2.8.0 to 2.8.1 in /web (#4178)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:05:40 +01:00
6ebfb5138c core: bump python from 3.11.0-slim-bullseye to 3.11.1-slim-bullseye (#4185)
Bumps python from 3.11.0-slim-bullseye to 3.11.1-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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:05:18 +01:00
ab8ed8599e web: bump @typescript-eslint/eslint-plugin from 5.45.1 to 5.46.0 in /web (#4187)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.45.1 to 5.46.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.46.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:05:03 +01:00
c76fb2eed0 web: bump lit from 2.4.1 to 2.5.0 in /web (#4188)
Bumps [lit](https://github.com/lit/lit/tree/HEAD/packages/lit) from 2.4.1 to 2.5.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.5.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:04:53 +01:00
4d8978ea90 bleuprints: fix flaky test
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-09 11:04:44 +00:00
64540cc870 core: bump certifi from 2022.9.24 to 2022.12.7 (#4184) 2022-12-08 21:44:08 +02:00
5b05884a2b web: bump typescript from 4.9.3 to 4.9.4 in /web (#4180) 2022-12-08 20:53:53 +02:00
eef3ef2165 core: bump golang from 1.19.3-bullseye to 1.19.4-bullseye (#4168) 2022-12-07 12:50:03 +02:00
235296c749 core: bump django from 4.1.3 to 4.1.4 (#4170) 2022-12-07 12:49:18 +02:00
8d13235b74 blueprints: fixed bug causing filtering with an empty query (#4106)
* Fixed bug causing filtering with an empty query

Fixed bug allowing blueprint import to filter for existing models using an empty query.

The code only checks if the `identifiers` dict is empty, but `__query_from_identifier` skips identifier member values of type `dict` or keys == `pk`, so it is possible to produce an empty query if an `identifier` consists of just `dict` type members or "pk" key. 

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* Added test case

* Added support for using dict fields as blueprint entry identifiers

* Disabled pylint too-many-locals for _validate_single

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>
2022-12-06 12:06:25 +01:00
5ef5c70490 web: bump @typescript-eslint/eslint-plugin from 5.45.0 to 5.45.1 in /web (#4159)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.45.0 to 5.45.1.
- [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.45.1/packages/eslint-plugin)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 11:44:33 +01:00
3fe627528e website: bump react-before-after-slider-component from 1.1.5 to 1.1.6 in /website (#4160)
website: bump react-before-after-slider-component in /website

Bumps [react-before-after-slider-component](https://github.com/smeleshkin/react-before-after-slider-component) from 1.1.5 to 1.1.6.
- [Release notes](https://github.com/smeleshkin/react-before-after-slider-component/releases)
- [Commits](https://github.com/smeleshkin/react-before-after-slider-component/compare/v.1.1.5...v.1.1.6)

---
updated-dependencies:
- dependency-name: react-before-after-slider-component
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 11:39:33 +01:00
674eeed763 web: bump eslint-plugin-lit from 1.6.1 to 1.7.0 in /web (#4161)
Bumps [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/43081j/eslint-plugin-lit/releases)
- [Commits](https://github.com/43081j/eslint-plugin-lit/compare/v1.6.1...v1.7.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 11:39:23 +01:00
4bd91180df web: bump @typescript-eslint/parser from 5.45.0 to 5.45.1 in /web (#4162)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.45.0 to 5.45.1.
- [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.45.1/packages/parser)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 11:39:03 +01:00
0af4824fa6 core: bump pylint from 2.15.7 to 2.15.8 (#4163)
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.15.7 to 2.15.8.
- [Release notes](https://github.com/PyCQA/pylint/releases)
- [Commits](https://github.com/PyCQA/pylint/compare/v2.15.7...v2.15.8)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 11:38:51 +01:00
64eb953593 web: bump @formatjs/intl-listformat from 7.1.6 to 7.1.7 in /web (#4151)
Bumps [@formatjs/intl-listformat](https://github.com/formatjs/formatjs) from 7.1.6 to 7.1.7.
- [Release notes](https://github.com/formatjs/formatjs/releases)
- [Commits](https://github.com/formatjs/formatjs/compare/@formatjs/intl-listformat@7.1.6...@formatjs/intl-listformat@7.1.7)

---
updated-dependencies:
- dependency-name: "@formatjs/intl-listformat"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 13:32:04 +01:00
45704cf20a web: bump eslint from 8.28.0 to 8.29.0 in /web (#4150)
Bumps [eslint](https://github.com/eslint/eslint) from 8.28.0 to 8.29.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.28.0...v8.29.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 13:31:54 +01:00
b5714afac7 core: bump goauthentik.io/api/v3 from 3.2022111.1 to 3.2022112.1 (#4152)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022111.1 to 3.2022112.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022111.1...v3.2022112.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 13:31:30 +01:00
ff109206fd core: bump selenium from 4.7.0 to 4.7.2 (#4153)
Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.7.0 to 4.7.2.
- [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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 13:31:16 +01:00
49bd028363 website/docs: update release notes
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-03 13:10:16 +02:00
44bf9a890e release: 2022.11.3 2022-12-02 23:00:59 +02:00
b60c6d4144 web: bump API Client
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-02 23:00:45 +02:00
ef239e6430 web: bump API Client version (#4142) 2022-12-02 17:29:09 +01:00
58cd6007b2 Merge branch 'version-2022.11' 2022-12-02 18:12:38 +02:00
1dcf6e8962 web: bump API Client version (#4141)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-12-02 16:17:37 +01:00
db95dfe38d security: fix CVE 2022 46145 (#4140)
* add flow authentication requirement

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

* add website for cve

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

* add tests

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

* flows: handle FlowNonApplicableException without policy result

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

* add release notes

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-02 16:14:25 +01:00
860c85d012 website/integrations: Update Bookstack SAML settings Documentation (#4137)
Update Bookstack SAML settings

Enabled AUTH_AUTO_INITIATE=true to reduce amount of clicks needed to proceed to Bookstack and give a propper SSO experience. If user is not logged in elsewhere already, authentik's login page will still be displayed.

Edited SAML2_DISPLAY_NAME_ATTRIBUTES so it actually works. The previous "Name" entry is non-functional and does not parse. When this is the case, or the field is empty, usernames in Bookstack default to user's email address. Entries here need to be in line with Active Directory Federation Services' Role of Claims found here: https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/technical-reference/the-role-of-claims. Additionally, this will use the user's authentik username rather than real/full name.

Enabled Group Sync by default for easier administration for sysadmins. SAML2_GROUP_ATTRIBUTE also needed to be in line with Active Directory Federation Services' Role of Claims

Signed-off-by: Avsynthe <102600593+Avsynthe@users.noreply.github.com>

Signed-off-by: Avsynthe <102600593+Avsynthe@users.noreply.github.com>
2022-12-02 11:46:44 +01:00
6ca1654129 lifecycle: don't set user/group in gunicorn
closes #4098 closes #3236

the user and group are inherited from the parent process so this isnt required

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-02 12:42:55 +02:00
a2dc594a44 web: bump @sentry/browser from 7.22.0 to 7.23.0 in /web (#4131)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.22.0 to 7.23.0.
- [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/7.22.0...7.23.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-02 09:52:53 +01:00
c6bc8e2ddf web: bump decode-uri-component from 0.2.0 to 0.2.2 in /web (#4136)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-02 09:52:23 +01:00
48a234e86f web: bump @sentry/tracing from 7.22.0 to 7.23.0 in /web (#4132) 2022-12-02 09:48:14 +01:00
cf521eba5a web: bump @formatjs/intl-listformat from 7.1.4 to 7.1.6 in /web (#4133) 2022-12-02 09:48:04 +01:00
52ebc78aaa core: bump selenium from 4.6.1 to 4.7.0 (#4134) 2022-12-02 09:47:53 +01:00
1f7d52c5ce blueprints: Support nested custom tags in !Find and !Format tags (#4127)
* Added support for nested tags to !Find and !Format

* Added tests

* Fix variable names

* Added docs

* Fixed small mistake in tests

* Fixed variable names

* Broke example into multiple lines
2022-12-01 16:10:26 +01:00
3251bdc220 events: improve handling creation of events with non-pickleable objects
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-01 15:56:28 +02:00
93fee5f0e5 web: fix authentification with Plex on iOS (#4095)
* web: fix authentification with Plex on iOS

Fixes issue #3822

* fixup

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

* add fallback button

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

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-12-01 13:32:00 +01:00
46c8db7f4b web: bump @codemirror/lang-html from 6.2.0 to 6.4.0 in /web (#4129)
Bumps [@codemirror/lang-html](https://github.com/codemirror/lang-html) from 6.2.0 to 6.4.0.
- [Release notes](https://github.com/codemirror/lang-html/releases)
- [Changelog](https://github.com/codemirror/lang-html/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-html/compare/6.2.0...6.4.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-01 09:57:20 +01:00
fc74c0209a web: bump pyright from 1.1.281 to 1.1.282 in /web (#4128)
Bumps [pyright](https://github.com/Microsoft/pyright/tree/HEAD/packages/pyright) from 1.1.281 to 1.1.282.
- [Release notes](https://github.com/Microsoft/pyright/releases)
- [Commits](https://github.com/Microsoft/pyright/commits/1.1.282/packages/pyright)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-01 09:53:23 +01:00
07bfc3da1e core: bump twilio from 7.15.3 to 7.15.4 (#4130)
Bumps [twilio](https://github.com/twilio/twilio-python) from 7.15.3 to 7.15.4.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/7.15.3...7.15.4)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-01 09:50:14 +01:00
cf40e5047e policies: don't log context when policy returns None
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-30 14:43:47 +02:00
d5329432fe lib: fix uploaded files not being saved correctly, add tests
closes #4110 #4109 #4107

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-30 12:48:33 +02:00
8a926aaa73 Revert "web: bump @codemirror/lang-html from 6.2.0 to 6.3.1 in /web (#4122)"
This reverts commit 17fc775fd3.
2022-11-30 10:42:28 +02:00
5156aeee0f policies/password: Always add generic message to failing zxcvbn check (#4100)
* Always add generic message to failing zxcvbn password policy

Depending on the settings, sometimes a password policy that checks a password with the zxcvbn tool can fail without any message.

For example:
```
$ echo  'Awdccdw1234' | zxcvbn | jq | grep "feedback" -A 5 -B 1
Password: 
  "score": 3,
  "feedback": {
    "warning": "",
    "suggestions": []
  }
}
```

As seen above the tool does not produce any warnings or suggestions for the given password, but if the password policy is set to have a zxcvbn threshold of 3, the policy will silently fail without communicating the reason to the user. 

There are two ways to handle this:
1. Always add a generic "password is too weak" message when the policy fails.
2. Check if there are any suggestions or warnings from the zxcvbn tool and only add the generic message if not.

I personally prefer 1. This way the generic message will  be shown whenever the policy fails, and will get combined with extra "tips" whenever zxcvbn has some.



Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* Update authentik/policies/password/models.py

Co-authored-by: Jens L. <jens@beryju.org>
Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* Added test case

* fix black formatting

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

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens L. <jens@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-30 07:58:16 +00:00
1690812936 web: bump @sentry/browser from 7.21.1 to 7.22.0 in /web (#4120)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.21.1 to 7.22.0.
- [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/7.21.1...7.22.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:46:22 +01:00
c693a2c3f4 web: bump @babel/core from 7.20.2 to 7.20.5 in /web (#4112)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.20.2 to 7.20.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.20.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:46:13 +01:00
d6cac5c765 web: bump @typescript-eslint/eslint-plugin from 5.44.0 to 5.45.0 in /web (#4116)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.44.0 to 5.45.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.45.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:46:01 +01:00
2722b9b7ea web: bump @rollup/plugin-typescript from 10.0.0 to 10.0.1 in /web (#4115)
Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 10.0.0 to 10.0.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-v10.0.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:38:15 +01:00
014fc6169a core: bump github.com/go-openapi/runtime from 0.24.2 to 0.25.0 (#4118)
Bumps [github.com/go-openapi/runtime](https://github.com/go-openapi/runtime) from 0.24.2 to 0.25.0.
- [Release notes](https://github.com/go-openapi/runtime/releases)
- [Commits](https://github.com/go-openapi/runtime/compare/v0.24.2...v0.25.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:37:48 +01:00
a7a722c9c0 web: bump @typescript-eslint/parser from 5.44.0 to 5.45.0 in /web (#4114)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.44.0 to 5.45.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.45.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:37:39 +01:00
da581dde70 web: bump @babel/plugin-proposal-decorators from 7.20.2 to 7.20.5 in /web (#4117)
web: bump @babel/plugin-proposal-decorators in /web

Bumps [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) from 7.20.2 to 7.20.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.20.5/packages/babel-plugin-proposal-decorators)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:37:29 +01:00
17fc775fd3 web: bump @codemirror/lang-html from 6.2.0 to 6.3.1 in /web (#4122)
Bumps [@codemirror/lang-html](https://github.com/codemirror/lang-html) from 6.2.0 to 6.3.1.
- [Release notes](https://github.com/codemirror/lang-html/releases)
- [Changelog](https://github.com/codemirror/lang-html/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-html/compare/6.2.0...6.3.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:36:42 +01:00
eb57c787f3 web: bump @sentry/tracing from 7.21.1 to 7.22.0 in /web (#4123)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.21.1 to 7.22.0.
- [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/7.21.1...7.22.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:36:31 +01:00
97e789323a web: bump @formatjs/intl-listformat from 7.1.3 to 7.1.4 in /web (#4121)
Bumps [@formatjs/intl-listformat](https://github.com/formatjs/formatjs) from 7.1.3 to 7.1.4.
- [Release notes](https://github.com/formatjs/formatjs/releases)
- [Commits](https://github.com/formatjs/formatjs/compare/@formatjs/intl-listformat@7.1.3...@formatjs/intl-listformat@7.1.4)

---
updated-dependencies:
- dependency-name: "@formatjs/intl-listformat"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:36:23 +01:00
290f576641 core: bump pylint from 2.15.6 to 2.15.7 (#4124)
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.15.6 to 2.15.7.
- [Release notes](https://github.com/PyCQA/pylint/releases)
- [Commits](https://github.com/PyCQA/pylint/compare/v2.15.6...v2.15.7)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 08:36:14 +01:00
9723aa11df root: include security policy in website container
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-29 00:05:42 +01:00
4e04461820 website/docs: Change Kubernetes ingress apiVersion out of beta (#4099)
* Change Kubernetes ingress apiVersion out of beta

* fix lint

Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-28 16:42:59 +01:00
147ebf1a5e root: rework and expand security policy
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-28 12:10:53 +01:00
e22fce02f8 stages/authenticator_validate: improve validation for not_configured_action
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-28 10:52:51 +01:00
3b8cb9e525 web/flows: fix display for long redirect URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-28 10:30:27 +01:00
beffb72e3b web: bump @rollup/plugin-babel from 6.0.2 to 6.0.3 in /web (#4103)
Bumps [@rollup/plugin-babel](https://github.com/rollup/plugins/tree/HEAD/packages/babel) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/babel/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/babel-v6.0.3/packages/babel)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 10:25:06 +01:00
b5c53d5e40 web: bump @rollup/plugin-typescript from 9.0.2 to 10.0.0 in /web (#4101)
Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 9.0.2 to 10.0.0.
- [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-v10.0.0/packages/typescript)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 10:24:45 +01:00
477dbc6daf web: bump @rollup/plugin-commonjs from 23.0.2 to 23.0.3 in /web (#4102) 2022-11-28 10:06:26 +01:00
3aaabdcc9d core: bump pycryptodome from 3.15.0 to 3.16.0 (#4104) 2022-11-28 10:06:17 +01:00
d045b0be1a core: bump selenium from 4.6.0 to 4.6.1 (#4105) 2022-11-28 10:06:06 +01:00
e2bd96c5de stages/authenticator_validate: fix validation to ensure configuration stage is set
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-25 21:37:52 +01:00
be9790ef8a internal: reuse http transport to prevent leaking connections (#3996)
* Fix: Using the same http transport as the api

* fix: Using global tlsTransport instead of newly created one
2022-11-25 18:24:01 +01:00
f8ef2b666f events: fix incorrect EventAction being used
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-25 11:53:05 +01:00
7bc63791c9 root: update deprecation warnings
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-25 11:47:28 +01:00
a9909fcf6d providers/oauth2: set amr values based on login event
closes #4070

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-25 11:21:59 +01:00
1fa9b3a996 providers/saml: set AuthnContextClassRef based on login event
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#4070
2022-11-25 11:21:45 +01:00
5019346ab6 events: save login event in session after login
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#4070
2022-11-25 11:21:00 +01:00
f22f1ebcde stages/authenticator_validate: save used mfa devices in login event
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-25 10:47:49 +01:00
1e328436d8 web: bump @codemirror/legacy-modes from 6.3.0 to 6.3.1 in /web (#4084)
Bumps [@codemirror/legacy-modes](https://github.com/codemirror/legacy-modes) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/codemirror/legacy-modes/releases)
- [Changelog](https://github.com/codemirror/legacy-modes/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/legacy-modes/compare/6.3.0...6.3.1)

---
updated-dependencies:
- dependency-name: "@codemirror/legacy-modes"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-25 10:47:30 +01:00
cb9a759aa0 web: bump @trivago/prettier-plugin-sort-imports from 3.4.0 to 4.0.0 in /web (#4085)
web: bump @trivago/prettier-plugin-sort-imports in /web

Bumps [@trivago/prettier-plugin-sort-imports](https://github.com/trivago/prettier-plugin-sort-imports) from 3.4.0 to 4.0.0.
- [Release notes](https://github.com/trivago/prettier-plugin-sort-imports/releases)
- [Changelog](https://github.com/trivago/prettier-plugin-sort-imports/blob/master/CHANGELOG.md)
- [Commits](https://github.com/trivago/prettier-plugin-sort-imports/compare/v3.4.0...v4.0.0)

---
updated-dependencies:
- dependency-name: "@trivago/prettier-plugin-sort-imports"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-25 10:47:09 +01:00
b80c528531 core: bump importlib-metadata from 5.0.0 to 5.1.0 (#4086)
Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 5.0.0 to 5.1.0.
- [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/v5.0.0...v5.1.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-25 10:46:49 +01:00
e03d2c06a8 core: bump structlog from 22.1.0 to 22.3.0 (#4087)
Bumps [structlog](https://github.com/hynek/structlog) from 22.1.0 to 22.3.0.
- [Release notes](https://github.com/hynek/structlog/releases)
- [Changelog](https://github.com/hynek/structlog/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/structlog/compare/22.1.0...22.3.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-25 10:46:09 +01:00
501d63b3aa website/docs: add notice for unique Base DN (#4073)
* providers/ldap: updates documentation related to issue #4038

Signed-off-by: John Arrandale <bootsie227@gmail.com>

* providers/ldap: adheres to the CI prettier-check

Signed-off-by: John Arrandale <bootsie227@gmail.com>
2022-11-24 20:52:13 +01:00
1c2cdfe06a web/flows: improve error messages for failed duo push
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-24 13:42:13 +01:00
118555c97a web: bump @sentry/tracing from 7.21.0 to 7.21.1 in /web (#4078)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.21.0 to 7.21.1.
- [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/7.21.0...7.21.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:18:12 +01:00
6af9fbc94e web: bump prettier from 2.7.1 to 2.8.0 in /web (#4075)
Bumps [prettier](https://github.com/prettier/prettier) from 2.7.1 to 2.8.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.7.1...2.8.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:17:57 +01:00
3020f9506e web: bump @types/mermaid from 9.1.0 to 9.2.0 in /web (#4076)
Bumps [@types/mermaid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mermaid) from 9.1.0 to 9.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mermaid)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:11:21 +01:00
ce9c6a9689 website: bump prettier from 2.7.1 to 2.8.0 in /website (#4074)
Bumps [prettier](https://github.com/prettier/prettier) from 2.7.1 to 2.8.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.7.1...2.8.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:11:11 +01:00
8f2d573721 web: bump pyright from 1.1.280 to 1.1.281 in /web (#4077)
Bumps [pyright](https://github.com/Microsoft/pyright/tree/HEAD/packages/pyright) from 1.1.280 to 1.1.281.
- [Release notes](https://github.com/Microsoft/pyright/releases)
- [Commits](https://github.com/Microsoft/pyright/commits/1.1.281/packages/pyright)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:10:57 +01:00
97c31d0a21 web: bump @sentry/browser from 7.21.0 to 7.21.1 in /web (#4079)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.21.0 to 7.21.1.
- [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/7.21.0...7.21.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:10:49 +01:00
46d28d8082 core: bump goauthentik.io/api/v3 from 3.2022110.1 to 3.2022111.1 (#4080)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2022110.1 to 3.2022111.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2022110.1...v3.2022111.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:10:36 +01:00
d248dd5b1b core: bump urllib3 from 1.26.12 to 1.26.13 (#4081)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.12 to 1.26.13.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.13/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.12...1.26.13)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-24 12:10:27 +01:00
474677017f web/admin: fix empty request being sent due to multiple forms in duo import modal
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-24 12:08:06 +01:00
0813a49ca5 web/admin: clarify phrasing that user ID is required
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-24 11:37:54 +01:00
d0308a8239 stages/authenticator_validate: log duo error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-24 11:36:43 +01:00
6843c8389b stages/authenticator_duo: fix imported duo devices not being confirmed
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-11-24 11:36:34 +01:00
7b0f89398d web: bump API Client version (#4071)
Signed-off-by: GitHub <noreply@github.com>

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: BeryJu <BeryJu@users.noreply.github.com>
2022-11-23 11:18:38 +01:00
97b867298a Merge branch 'version-2022.11' 2022-11-23 10:38:49 +01:00
76d5cbcea9 web: bump @sentry/tracing from 7.20.1 to 7.21.0 in /web (#4068)
Bumps [@sentry/tracing](https://github.com/getsentry/sentry-javascript) from 7.20.1 to 7.21.0.
- [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/7.20.1...7.21.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-23 10:38:28 +01:00
2b925536d3 web: bump @patternfly/patternfly from 4.219.2 to 4.221.2 in /web (#4067)
Bumps [@patternfly/patternfly](https://github.com/patternfly/patternfly) from 4.219.2 to 4.221.2.
- [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.219.2...prerelease-v4.221.2)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-23 10:37:39 +01:00
4baa5ae7a2 web: bump chart.js from 3.9.1 to 4.0.1 in /web (#4066)
Bumps [chart.js](https://github.com/chartjs/Chart.js) from 3.9.1 to 4.0.1.
- [Release notes](https://github.com/chartjs/Chart.js/releases)
- [Commits](https://github.com/chartjs/Chart.js/compare/v3.9.1...v4.0.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-23 10:37:31 +01:00
3f9d4f7083 web: bump @sentry/browser from 7.20.1 to 7.21.0 in /web (#4065)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 7.20.1 to 7.21.0.
- [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/7.20.1...7.21.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-23 10:37:23 +01:00
10186a2e67 core: bump sentry-sdk from 1.11.0 to 1.11.1 (#4069)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.11.0 to 1.11.1.
- [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.11.0...1.11.1)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-23 10:35:03 +01:00
255 changed files with 47652 additions and 3161 deletions

View File

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

View File

@ -1,8 +1,8 @@
env
static
htmlcov
*.env.yml
**/node_modules
dist/**
build/**
build_docs/**
Dockerfile

View File

@ -99,7 +99,7 @@ jobs:
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.4.0
uses: helm/kind-action@v1.5.0
- name: run integration
run: |
poetry run make test-integration
@ -208,6 +208,9 @@ jobs:
- name: Building Docker Image
uses: docker/build-push-action@v3
with:
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
tags: |
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}

View File

@ -31,6 +31,9 @@ jobs:
uses: docker/build-push-action@v3
with:
push: ${{ github.event_name == 'release' }}
secrets:
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
tags: |
beryju/authentik:${{ steps.ev.outputs.version }},
beryju/authentik:${{ steps.ev.outputs.versionFamily }},
@ -39,7 +42,8 @@ jobs:
ghcr.io/goauthentik/server:${{ steps.ev.outputs.versionFamily }},
ghcr.io/goauthentik/server:latest
platforms: linux/amd64,linux/arm64
context: .
build-args: |
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
build-outpost:
runs-on: ubuntu-latest
strategy:
@ -84,6 +88,11 @@ jobs:
ghcr.io/goauthentik/${{ matrix.type }}:latest
file: ${{ matrix.type }}.Dockerfile
platforms: linux/amd64,linux/arm64
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
build-args: |
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
build-outpost-binary:
timeout-minutes: 120
runs-on: ubuntu-latest
@ -161,11 +170,9 @@ jobs:
if: ${{ github.event_name == 'release' }}
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: beryjuorg
SENTRY_ORG: authentik-security-inc
SENTRY_PROJECT: authentik
SENTRY_URL: https://sentry.beryju.org
with:
version: authentik@${{ steps.ev.outputs.version }}
environment: beryjuorg-prod
sourcemaps: './web/dist'
url_prefix: '~/static/dist'

4
.gitignore vendored
View File

@ -194,11 +194,9 @@ pip-selfcheck.json
/static/
local.env.yml
# Selenium Screenshots
selenium_screenshots/
backups/
media/
*mmdb
.idea/
/gen-*/
data/

View File

@ -24,7 +24,11 @@
"!Find sequence",
"!KeyOf scalar",
"!Context scalar",
"!Format sequence"
"!Context sequence",
"!Format sequence",
"!Condition sequence",
"!Env sequence",
"!Env scalar"
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifierEnding": "index",

View File

@ -20,7 +20,7 @@ WORKDIR /work/web
RUN npm ci && npm run build
# Stage 3: Poetry to requirements.txt export
FROM docker.io/python:3.11.0-slim-bullseye AS poetry-locker
FROM docker.io/python:3.11.1-slim-bullseye AS poetry-locker
WORKDIR /work
COPY ./pyproject.toml /work
@ -31,7 +31,7 @@ RUN pip install --no-cache-dir poetry && \
poetry export -f requirements.txt --dev --output requirements-dev.txt
# Stage 4: Build go proxy
FROM docker.io/golang:1.19.3-bullseye AS go-builder
FROM docker.io/golang:1.19.4-bullseye AS go-builder
WORKDIR /work
@ -46,8 +46,22 @@ COPY ./go.sum /work/go.sum
RUN go build -o /work/authentik ./cmd/server/
# Stage 5: Run
FROM docker.io/python:3.11.0-slim-bullseye AS final-image
# Stage 5: MaxMind GeoIP
FROM docker.io/maxmindinc/geoipupdate:v4.10 as geoip
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City"
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
--mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
mkdir -p /usr/share/GeoIP && \
/bin/sh -c "\
export GEOIPUPDATE_ACCOUNT_ID=$(cat /run/secrets/GEOIPUPDATE_ACCOUNT_ID); \
export GEOIPUPDATE_LICENSE_KEY=$(cat /run/secrets/GEOIPUPDATE_LICENSE_KEY); \
/usr/bin/entry.sh || exit 0 \
"
# Stage 6: Run
FROM docker.io/python:3.11.1-slim-bullseye AS final-image
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,6 +74,7 @@ ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
COPY --from=poetry-locker /work/requirements.txt /
COPY --from=poetry-locker /work/requirements-dev.txt /
COPY --from=geoip /usr/share/GeoIP /geoip
RUN apt-get update && \
# Required for installing pip packages

View File

@ -5,13 +5,13 @@
---
[![Join Discord](https://img.shields.io/discord/809154715984199690?label=Discord&style=for-the-badge)](https://goauthentik.io/discord)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/goauthentik/authentik/authentik-ci-main?label=core%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-main.yml)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/goauthentik/authentik/authentik-ci-outpost?label=outpost%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-outpost.yml)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/goauthentik/authentik/authentik-ci-web?label=web%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-web.yml)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/goauthentik/authentik/ci-main.yml?branch=main&label=core%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-main.yml)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/goauthentik/authentik/ci-outpost.yml?branch=main&label=outpost%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-outpost.yml)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/goauthentik/authentik/ci-web.yml?branch=main&label=web%20build&style=for-the-badge)](https://github.com/goauthentik/authentik/actions/workflows/ci-web.yml)
[![Code Coverage](https://img.shields.io/codecov/c/gh/goauthentik/authentik?style=for-the-badge)](https://codecov.io/gh/goauthentik/authentik)
![Docker pulls](https://img.shields.io/docker/pulls/beryju/authentik.svg?style=for-the-badge)
![Latest version](https://img.shields.io/docker/v/beryju/authentik?sort=semver&style=for-the-badge)
[![](https://img.shields.io/badge/Help%20translate-transifex-blue?style=for-the-badge)](https://www.transifex.com/beryjuorg/authentik/)
[![](https://img.shields.io/badge/Help%20translate-transifex-blue?style=for-the-badge)](https://www.transifex.com/authentik/authentik/)
## What is authentik?

View File

@ -6,8 +6,8 @@ Authentik takes security very seriously. We follow the rules of [responsible dis
| Version | Supported |
| --------- | ------------------ |
| 2022.10.x | :white_check_mark: |
| 2022.11.x | :white_check_mark: |
| 2022.12.x | :white_check_mark: |
## Reporting a Vulnerability
@ -41,4 +41,4 @@ To report a vulnerability, send an email to [security@goauthentik.io](mailto:sec
## Getting security notifications
To get security notifications, join the [discord](https://goauthentik.io/discord) server. In the future there will be a mailing list too.
To get security notifications, subscribe to the mailing list [here](https://groups.google.com/g/authentik-security-announcements) or join the [discord](https://goauthentik.io/discord) server.

View File

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

View File

@ -11,7 +11,6 @@ from authentik.core.middleware import CTX_AUTH_VIA
from authentik.core.models import Token, TokenIntents, User
from authentik.outposts.models import Outpost
from authentik.providers.oauth2.constants import SCOPE_AUTHENTIK_API
from authentik.providers.oauth2.models import RefreshToken
LOGGER = get_logger()
@ -33,6 +32,8 @@ def validate_auth(header: bytes) -> Optional[str]:
def bearer_auth(raw_header: bytes) -> Optional[User]:
"""raw_header in the Format of `Bearer ....`"""
from authentik.providers.oauth2.models import RefreshToken
auth_credentials = validate_auth(raw_header)
if not auth_credentials:
return None

View File

@ -49,11 +49,12 @@ from authentik.policies.hibp.api import HaveIBeenPwendPolicyViewSet
from authentik.policies.password.api import PasswordPolicyViewSet
from authentik.policies.reputation.api import ReputationPolicyViewSet, ReputationViewSet
from authentik.providers.ldap.api import LDAPOutpostConfigViewSet, LDAPProviderViewSet
from authentik.providers.oauth2.api.provider import OAuth2ProviderViewSet
from authentik.providers.oauth2.api.scope import ScopeMappingViewSet
from authentik.providers.oauth2.api.providers import OAuth2ProviderViewSet
from authentik.providers.oauth2.api.scopes import ScopeMappingViewSet
from authentik.providers.oauth2.api.tokens import AuthorizationCodeViewSet, RefreshTokenViewSet
from authentik.providers.proxy.api import ProxyOutpostConfigViewSet, ProxyProviderViewSet
from authentik.providers.saml.api import SAMLPropertyMappingViewSet, SAMLProviderViewSet
from authentik.providers.saml.api.property_mapping import SAMLPropertyMappingViewSet
from authentik.providers.saml.api.providers import SAMLProviderViewSet
from authentik.sources.ldap.api import LDAPPropertyMappingViewSet, LDAPSourceViewSet
from authentik.sources.oauth.api.source import OAuthSourceViewSet
from authentik.sources.oauth.api.source_connection import UserOAuthSourceConnectionViewSet

View File

@ -62,6 +62,12 @@
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"attrs": {
"type": "object",
"properties": {

View File

@ -92,7 +92,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel):
if ":" in url.path:
path, _, ref = path.partition(":")
client = NewClient(
f"{url.scheme}://{url.hostname}",
f"https://{url.hostname}",
WithUserAgent(authentik_user_agent()),
WithUsernamePassword(url.username, url.password),
WithDefaultName(path),
@ -135,12 +135,11 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel):
def retrieve(self) -> str:
"""Retrieve blueprint contents"""
if self.path.startswith("oci://"):
return self.retrieve_oci()
full_path = Path(CONFIG.y("blueprints_dir")).joinpath(Path(self.path))
if full_path.exists():
LOGGER.debug("Blueprint path exists locally", instance=self)
with full_path.open("r", encoding="utf-8") as _file:
return _file.read()
return self.retrieve_oci()
with full_path.open("r", encoding="utf-8") as _file:
return _file.read()
@property
def serializer(self) -> Serializer:

View File

@ -0,0 +1,21 @@
version: 1
entries:
- identifiers:
name: "%(id1)s"
slug: "%(id1)s"
model: authentik_flows.flow
conditions:
- true
attrs:
designation: stage_configuration
title: foo
- identifiers:
name: "%(id2)s"
slug: "%(id2)s"
model: authentik_flows.flow
conditions:
- true
- true
attrs:
designation: stage_configuration
title: foo

View File

@ -0,0 +1,21 @@
version: 1
entries:
- identifiers:
name: "%(id1)s"
slug: "%(id1)s"
model: authentik_flows.flow
conditions:
- false
attrs:
designation: stage_configuration
title: foo
- identifiers:
name: "%(id2)s"
slug: "%(id2)s"
model: authentik_flows.flow
conditions:
- true
- false
attrs:
designation: stage_configuration
title: foo

View File

@ -1,7 +1,7 @@
version: 1
entries:
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: absent
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: absent

View File

@ -1,10 +1,10 @@
version: 1
entries:
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: created
attrs:
designation: stage_configuration
title: foo
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: created
attrs:
designation: stage_configuration
title: foo

View File

@ -1,10 +1,10 @@
version: 1
entries:
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: present
attrs:
designation: stage_configuration
title: foo
- identifiers:
name: "%(id)s"
slug: "%(id)s"
model: authentik_flows.flow
state: present
attrs:
designation: stage_configuration
title: foo

View File

@ -1,12 +1,12 @@
version: 1
entries:
- identifiers:
pk: cb954fd4-65a5-4ad9-b1ee-180ee9559cf4
model: authentik_stages_prompt.prompt
attrs:
field_key: username
label: Username
type: username
required: true
placeholder: Username
order: 0
- identifiers:
pk: cb954fd4-65a5-4ad9-b1ee-180ee9559cf4
model: authentik_stages_prompt.prompt
attrs:
field_key: username
label: Username
type: username
required: true
placeholder: Username
order: 0

View File

@ -1,10 +1,100 @@
version: 1
context:
foo: bar
policy_property: name
policy_property_value: foo-bar-baz-qux
entries:
- attrs:
expression: return True
identifiers:
name: !Format [foo-%s-%s, !Context foo, !Context bar]
id: default-source-enrollment-if-username
model: authentik_policies_expression.expressionpolicy
- model: authentik_sources_oauth.oauthsource
identifiers:
slug: test
attrs:
name: test
provider_type: github
consumer_key: !Env foo
consumer_secret: !Env [bar, baz]
authentication_flow:
!Find [
authentik_flows.Flow,
[slug, default-source-authentication],
]
enrollment_flow:
!Find [authentik_flows.Flow, [slug, default-source-enrollment]]
- attrs:
expression: return True
identifiers:
name: !Format [foo-%s-%s-%s, !Context foo, !Context bar, qux]
id: policy
model: authentik_policies_expression.expressionpolicy
- attrs:
attributes:
policy_pk1:
!Format [
"%s-%s",
!Find [
authentik_policies_expression.expressionpolicy,
[
!Context policy_property,
!Context policy_property_value,
],
[expression, return True],
],
suffix,
]
policy_pk2: !Format ["%s-%s", !KeyOf policy, suffix]
boolAnd:
!Condition [AND, !Context foo, !Format ["%s", "a_string"], 1]
boolNand:
!Condition [NAND, !Context foo, !Format ["%s", "a_string"], 1]
boolOr:
!Condition [
OR,
!Context foo,
!Format ["%s", "a_string"],
null,
]
boolNor:
!Condition [
NOR,
!Context foo,
!Format ["%s", "a_string"],
null,
]
boolXor:
!Condition [XOR, !Context foo, !Format ["%s", "a_string"], 1]
boolXnor:
!Condition [XNOR, !Context foo, !Format ["%s", "a_string"], 1]
boolComplex:
!Condition [
XNOR,
!Condition [AND, !Context non_existing],
!Condition [NOR, a string],
!Condition [XOR, null],
]
if_true_complex:
!If [
true,
{
dictionary:
{
with: { keys: "and_values" },
and_nested_custom_tags:
!Format ["foo-%s", !Context foo],
},
},
null,
]
if_false_complex:
!If [
!Condition [AND, false],
null,
[list, with, items, !Format ["foo-%s", !Context foo]],
]
if_true_simple: !If [!Context foo, true, text]
if_false_simple: !If [null, false, 2]
identifiers:
name: test
conditions:
- !Condition [AND, true, true, text]
- true
- text
model: authentik_core.group

View File

@ -1,13 +1,17 @@
"""Test blueprints v1"""
from os import environ
from django.test import TransactionTestCase
from authentik.blueprints.tests import load_yaml_fixture
from authentik.blueprints.v1.exporter import FlowExporter
from authentik.blueprints.v1.importer import Importer, transaction_rollback
from authentik.core.models import Group
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
from authentik.lib.generators import generate_id
from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
from authentik.stages.user_login.models import UserLoginStage
@ -26,6 +30,61 @@ class TestBlueprintsV1(TransactionTestCase):
)
)
self.assertFalse(importer.validate()[0])
importer = Importer(
(
'{"version": 1, "entries": [{"attrs": {"name": "test"}, '
'"identifiers": {}, '
'"model": "authentik_core.Group"}]}'
)
)
self.assertFalse(importer.validate()[0])
def test_validated_import_dict_identifiers(self):
"""Test importing blueprints with dict identifiers."""
Group.objects.filter(name__istartswith="test").delete()
Group.objects.create(
name="test1",
attributes={
"key": ["value"],
"other_key": ["a_value", "other_value"],
},
)
Group.objects.create(
name="test2",
attributes={
"key": ["value"],
"other_key": ["diff_value", "other_diff_value"],
},
)
importer = Importer(
(
'{"version": 1, "entries": [{"attrs": {"name": "test999", "attributes": '
'{"key": ["updated_value"]}}, "identifiers": {"attributes": {"other_key": '
'["other_value"]}}, "model": "authentik_core.Group"}]}'
)
)
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
self.assertTrue(
Group.objects.filter(
name="test2",
attributes={
"key": ["value"],
"other_key": ["diff_value", "other_diff_value"],
},
)
)
self.assertTrue(
Group.objects.filter(
name="test999",
# All attributes used as identifiers are kept and merged with the
# new attributes declared in the blueprint
attributes={"key": ["updated_value"], "other_key": ["other_value"]},
)
)
self.assertFalse(Group.objects.filter(name="test1"))
def test_export_validate_import(self):
"""Test export and validate it"""
@ -74,11 +133,44 @@ class TestBlueprintsV1(TransactionTestCase):
def test_import_yaml_tags(self):
"""Test some yaml tags"""
ExpressionPolicy.objects.filter(name="foo-foo-bar").delete()
ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete()
Group.objects.filter(name="test").delete()
environ["foo"] = generate_id()
importer = Importer(load_yaml_fixture("fixtures/tags.yaml"), {"bar": "baz"})
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
self.assertTrue(ExpressionPolicy.objects.filter(name="foo-foo-bar"))
policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first()
self.assertTrue(policy)
self.assertTrue(
Group.objects.filter(
attributes={
"policy_pk1": str(policy.pk) + "-suffix",
"policy_pk2": str(policy.pk) + "-suffix",
"boolAnd": True,
"boolNand": False,
"boolOr": True,
"boolNor": False,
"boolXor": True,
"boolXnor": False,
"boolComplex": True,
"if_true_complex": {
"dictionary": {
"with": {"keys": "and_values"},
"and_nested_custom_tags": "foo-bar",
}
},
"if_false_complex": ["list", "with", "items", "foo-bar"],
"if_true_simple": True,
"if_false_simple": 2,
}
)
)
self.assertTrue(
OAuthSource.objects.filter(
slug="test",
consumer_key=environ["foo"],
)
)
def test_export_validate_import_policies(self):
"""Test export and validate it"""

View File

@ -0,0 +1,43 @@
"""Test blueprints v1"""
from django.test import TransactionTestCase
from authentik.blueprints.tests import load_yaml_fixture
from authentik.blueprints.v1.importer import Importer
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
class TestBlueprintsV1Conditions(TransactionTestCase):
"""Test Blueprints conditions attribute"""
def test_conditions_fulfilled(self):
"""Test conditions fulfilled"""
flow_slug1 = generate_id()
flow_slug2 = generate_id()
import_yaml = load_yaml_fixture(
"fixtures/conditions_fulfilled.yaml", id1=flow_slug1, id2=flow_slug2
)
importer = Importer(import_yaml)
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
# Ensure objects exist
flow: Flow = Flow.objects.filter(slug=flow_slug1).first()
self.assertEqual(flow.slug, flow_slug1)
flow: Flow = Flow.objects.filter(slug=flow_slug2).first()
self.assertEqual(flow.slug, flow_slug2)
def test_conditions_not_fulfilled(self):
"""Test conditions not fulfilled"""
flow_slug1 = generate_id()
flow_slug2 = generate_id()
import_yaml = load_yaml_fixture(
"fixtures/conditions_not_fulfilled.yaml", id1=flow_slug1, id2=flow_slug2
)
importer = Importer(import_yaml)
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
# Ensure objects do not exist
self.assertFalse(Flow.objects.filter(slug=flow_slug1))
self.assertFalse(Flow.objects.filter(slug=flow_slug2))

View File

@ -67,25 +67,8 @@ class TestBlueprintsV1Tasks(TransactionTestCase):
@CONFIG.patch("blueprints_dir", TMP)
def test_valid_updated(self):
"""Test valid file"""
BlueprintInstance.objects.filter(name="foo").delete()
with NamedTemporaryFile(mode="w+", suffix=".yaml", dir=TMP) as file:
file.write(
dump(
{
"version": 1,
"entries": [],
}
)
)
file.flush()
blueprints_discover() # pylint: disable=no-value-for-parameter
self.assertEqual(
BlueprintInstance.objects.first().last_applied_hash,
(
"e52bb445b03cd36057258dc9f0ce0fbed8278498ee1470e45315293e5f026d1b"
"d1f9b3526871c0003f5c07be5c3316d9d4a08444bd8fed1b3f03294e51e44522"
),
)
self.assertEqual(BlueprintInstance.objects.first().metadata, {})
file.write(
dump(
{
@ -99,18 +82,44 @@ class TestBlueprintsV1Tasks(TransactionTestCase):
)
file.flush()
blueprints_discover() # pylint: disable=no-value-for-parameter
blueprint = BlueprintInstance.objects.filter(name="foo").first()
self.assertEqual(
BlueprintInstance.objects.first().last_applied_hash,
blueprint.last_applied_hash,
(
"fc62fea96067da8592bdf90927246d0ca150b045447df93b0652a0e20a8bc327"
"681510b5db37ea98759c61f9a98dd2381f46a3b5a2da69dfb45158897f14e824"
"b86ec439b3857350714f070d2833490e736d9155d3d97b2cac13f3b352223e5a"
"1adbf8ec56fa616d46090cc4773ff9e46c4e509fde96b97de87dd21fa329ca1a"
),
)
self.assertEqual(blueprint.metadata, {"labels": {}, "name": "foo"})
file.write(
dump(
{
"version": 1,
"entries": [],
"metadata": {
"name": "foo",
"labels": {
"foo": "bar",
},
},
}
)
)
file.flush()
blueprints_discover() # pylint: disable=no-value-for-parameter
blueprint.refresh_from_db()
self.assertEqual(
blueprint.last_applied_hash,
(
"87b68b10131d2c9751ed308bba38f04734b9e2cdf8532ed617bc52979b063c49"
"2564f33f3d20ab9d5f0fd9e6eb77a13942e060199f147789cb7afab9690e72b5"
),
)
self.assertEqual(
BlueprintInstance.objects.first().metadata,
blueprint.metadata,
{
"name": "foo",
"labels": {},
"labels": {"foo": "bar"},
},
)

View File

@ -2,7 +2,10 @@
from collections import OrderedDict
from dataclasses import asdict, dataclass, field, is_dataclass
from enum import Enum
from typing import Any, Optional
from functools import reduce
from operator import ixor
from os import getenv
from typing import Any, Literal, Optional
from uuid import UUID
from django.apps import apps
@ -55,6 +58,7 @@ class BlueprintEntry:
model: str
state: BlueprintEntryDesiredState = field(default=BlueprintEntryDesiredState.PRESENT)
conditions: list[Any] = field(default_factory=list)
identifiers: dict[str, Any] = field(default_factory=dict)
attrs: Optional[dict[str, Any]] = field(default_factory=dict)
@ -99,6 +103,10 @@ class BlueprintEntry:
"""Get attributes of this entry, with all yaml tags resolved"""
return self.tag_resolver(self.identifiers, blueprint)
def check_all_conditions_match(self, blueprint: "Blueprint") -> bool:
"""Check all conditions of this entry match (evaluate to True)"""
return all(self.tag_resolver(self.conditions, blueprint))
@dataclass
class BlueprintMetadata:
@ -153,6 +161,26 @@ class KeyOf(YAMLTag):
)
class Env(YAMLTag):
"""Lookup environment variable with optional default"""
key: str
default: Optional[Any]
# pylint: disable=unused-argument
def __init__(self, loader: "BlueprintLoader", node: ScalarNode | SequenceNode) -> None:
super().__init__()
self.default = None
if isinstance(node, ScalarNode):
self.key = node.value
if isinstance(node, SequenceNode):
self.key = node.value[0].value
self.default = node.value[1].value
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
return getenv(self.key, self.default)
class Context(YAMLTag):
"""Lookup key from instance context"""
@ -188,11 +216,18 @@ class Format(YAMLTag):
self.format_string = node.value[0].value
self.args = []
for raw_node in node.value[1:]:
self.args.append(raw_node.value)
self.args.append(loader.construct_object(raw_node))
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
args = []
for arg in self.args:
if isinstance(arg, YAMLTag):
args.append(arg.resolve(entry, blueprint))
else:
args.append(arg)
try:
return self.format_string % tuple(self.args)
return self.format_string % tuple(args)
except TypeError as exc:
raise EntryInvalidError(exc)
@ -219,13 +254,93 @@ class Find(YAMLTag):
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
query = Q()
for cond in self.conditions:
query &= Q(**{cond[0]: cond[1]})
if isinstance(cond[0], YAMLTag):
query_key = cond[0].resolve(entry, blueprint)
else:
query_key = cond[0]
if isinstance(cond[1], YAMLTag):
query_value = cond[1].resolve(entry, blueprint)
else:
query_value = cond[1]
query &= Q(**{query_key: query_value})
instance = self.model_class.objects.filter(query).first()
if instance:
return instance.pk
return None
class Condition(YAMLTag):
"""Convert all values to a single boolean"""
mode: Literal["AND", "NAND", "OR", "NOR", "XOR", "XNOR"]
args: list[Any]
_COMPARATORS = {
# Using all and any here instead of from operator import iand, ior
# to improve performance
"AND": all,
"NAND": lambda args: not all(args),
"OR": any,
"NOR": lambda args: not any(args),
"XOR": lambda args: reduce(ixor, args) if len(args) > 1 else args[0],
"XNOR": lambda args: not (reduce(ixor, args) if len(args) > 1 else args[0]),
}
# pylint: disable=unused-argument
def __init__(self, loader: "BlueprintLoader", node: SequenceNode) -> None:
super().__init__()
self.mode = node.value[0].value
self.args = []
for raw_node in node.value[1:]:
self.args.append(loader.construct_object(raw_node))
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
args = []
for arg in self.args:
if isinstance(arg, YAMLTag):
args.append(arg.resolve(entry, blueprint))
else:
args.append(arg)
if not args:
raise EntryInvalidError("At least one value is required after mode selection.")
try:
comparator = self._COMPARATORS[self.mode.upper()]
return comparator(tuple(bool(x) for x in args))
except (TypeError, KeyError) as exc:
raise EntryInvalidError(exc)
class If(YAMLTag):
"""Select YAML to use based on condition"""
condition: Any
when_true: Any
when_false: Any
# pylint: disable=unused-argument
def __init__(self, loader: "BlueprintLoader", node: SequenceNode) -> None:
super().__init__()
self.condition = loader.construct_object(node.value[0])
self.when_true = loader.construct_object(node.value[1])
self.when_false = loader.construct_object(node.value[2])
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
if isinstance(self.condition, YAMLTag):
condition = self.condition.resolve(entry, blueprint)
else:
condition = self.condition
try:
return entry.tag_resolver(
self.when_true if condition else self.when_false,
blueprint,
)
except TypeError as exc:
raise EntryInvalidError(exc)
class BlueprintDumper(SafeDumper):
"""Dump dataclasses to yaml"""
@ -266,6 +381,9 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!Find", Find)
self.add_constructor("!Context", Context)
self.add_constructor("!Format", Format)
self.add_constructor("!Condition", Condition)
self.add_constructor("!If", If)
self.add_constructor("!Env", Env)
class EntryInvalidError(SentryIgnoredException):

View File

@ -132,15 +132,22 @@ class Importer:
main_query = Q(pk=attrs["pk"])
sub_query = Q()
for identifier, value in attrs.items():
if isinstance(value, dict):
continue
if identifier == "pk":
continue
sub_query &= Q(**{identifier: value})
if isinstance(value, dict):
sub_query &= Q(**{f"{identifier}__contains": value})
else:
sub_query &= Q(**{identifier: value})
return main_query | sub_query
# pylint: disable-msg=too-many-locals
def _validate_single(self, entry: BlueprintEntry) -> Optional[BaseSerializer]:
"""Validate a single entry"""
if not entry.check_all_conditions_match(self.__import):
self.logger.debug("One or more conditions of this entry are not fulfilled, skipping")
return None
model_app_label, model_name = entry.model.split(".")
model: type[SerializerModel] = registry.get_model(model_app_label, model_name)
# Don't use isinstance since we don't want to check for inheritance
@ -156,8 +163,6 @@ class Importer:
f"Serializer errors {serializer.errors}", serializer_errors=serializer.errors
) from exc
return serializer
if entry.identifiers == {}:
raise EntryInvalidError("No identifiers")
# If we try to validate without referencing a possible instance
# we'll get a duplicate error, hence we load the model here and return
@ -169,7 +174,12 @@ class Importer:
if isinstance(value, dict) and "pk" in value:
del updated_identifiers[key]
updated_identifiers[f"{key}"] = value["pk"]
existing_models = model.objects.filter(self.__query_from_identifier(updated_identifiers))
query = self.__query_from_identifier(updated_identifiers)
if not query:
raise EntryInvalidError("No or invalid identifiers")
existing_models = model.objects.filter(query)
serializer_kwargs = {}
model_instance = existing_models.first()
@ -198,7 +208,7 @@ class Importer:
full_data = self.__update_pks_for_attrs(entry.get_attrs(self.__import))
except ValueError as exc:
raise EntryInvalidError(exc) from exc
full_data.update(updated_identifiers)
always_merger.merge(full_data, updated_identifiers)
serializer_kwargs["data"] = full_data
serializer: Serializer = model().serializer(**serializer_kwargs)

View File

@ -196,9 +196,9 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
if not should_cache:
allowed_applications = self._get_allowed_applications(queryset)
if should_cache:
LOGGER.debug("Caching allowed application list")
allowed_applications = cache.get(user_app_cache_key(self.request.user.pk))
if not allowed_applications:
LOGGER.debug("Caching allowed application list")
allowed_applications = self._get_allowed_applications(queryset)
cache.set(
user_app_cache_key(self.request.user.pk),

View File

@ -2,13 +2,20 @@
from json import loads
from django.db.models.query import QuerySet
from django.http import Http404
from django_filters.filters import CharFilter, ModelMultipleChoiceFilter
from django_filters.filterset import FilterSet
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
from guardian.shortcuts import get_objects_for_user
from rest_framework.decorators import action
from rest_framework.fields import CharField, IntegerField, JSONField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ListSerializer, ModelSerializer, ValidationError
from rest_framework.viewsets import ModelViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter
from authentik.api.decorators import permission_required
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import is_dict
from authentik.core.models import Group, User
@ -134,3 +141,63 @@ class GroupViewSet(UsedByMixin, ModelViewSet):
if self.request.user.has_perm("authentik_core.view_group"):
return self._filter_queryset_for_list(queryset)
return super().filter_queryset(queryset)
@permission_required(None, ["authentik_core.add_user"])
@extend_schema(
request=inline_serializer(
"UserAccountSerializer",
{
"pk": IntegerField(required=True),
},
),
responses={
204: OpenApiResponse(description="User added"),
404: OpenApiResponse(description="User not found"),
},
)
@action(detail=True, methods=["POST"], pagination_class=None, filter_backends=[])
# pylint: disable=unused-argument, invalid-name
def add_user(self, request: Request, pk: str) -> Response:
"""Add user to group"""
group: Group = self.get_object()
user: User = (
get_objects_for_user(request.user, "authentik_core.view_user")
.filter(
pk=request.data.get("pk"),
)
.first()
)
if not user:
raise Http404
group.users.add(user)
return Response(status=204)
@permission_required(None, ["authentik_core.add_user"])
@extend_schema(
request=inline_serializer(
"UserAccountSerializer",
{
"pk": IntegerField(required=True),
},
),
responses={
204: OpenApiResponse(description="User added"),
404: OpenApiResponse(description="User not found"),
},
)
@action(detail=True, methods=["POST"], pagination_class=None, filter_backends=[])
# pylint: disable=unused-argument, invalid-name
def remove_user(self, request: Request, pk: str) -> Response:
"""Add user to group"""
group: Group = self.get_object()
user: User = (
get_objects_for_user(request.user, "authentik_core.view_user")
.filter(
pk=request.data.get("pk"),
)
.first()
)
if not user:
raise Http404
group.users.remove(user)
return Response(status=204)

View File

@ -2,7 +2,7 @@
from typing import Any
from django.db.models import Model
from rest_framework.fields import CharField, IntegerField
from rest_framework.fields import CharField, IntegerField, JSONField
from rest_framework.serializers import Serializer, SerializerMethodField, ValidationError
@ -23,6 +23,12 @@ class PassiveSerializer(Serializer):
return Model()
class PropertyMappingPreviewSerializer(PassiveSerializer):
"""Preview how the current user is mapped via the property mappings selected in a provider"""
preview = JSONField(read_only=True)
class MetaNameSerializer(PassiveSerializer):
"""Add verbose names to response"""

View File

@ -2,10 +2,14 @@
{% get_current_language as LANGUAGE_CODE %}
<script>
window.authentik = {};
window.authentik.locale = "{{ LANGUAGE_CODE }}";
window.authentik.config = JSON.parse('{{ config_json|escapejs }}');
window.authentik.tenant = JSON.parse('{{ tenant_json|escapejs }}');
window.authentik = {
locale: "{{ LANGUAGE_CODE }}",
config: JSON.parse('{{ config_json|escapejs }}'),
tenant: JSON.parse('{{ tenant_json|escapejs }}'),
versionFamily: "{{ version_family }}",
versionSubdomain: "{{ version_subdomain }}",
build: "{{ build }}",
};
window.addEventListener("DOMContentLoaded", () => {
{% for message in messages %}
window.dispatchEvent(

View File

@ -1,6 +1,8 @@
"""Test Applications API"""
from json import loads
from django.core.files.base import ContentFile
from django.test.client import BOUNDARY, MULTIPART_CONTENT, encode_multipart
from django.urls import reverse
from rest_framework.test import APITestCase
@ -21,7 +23,7 @@ class TestApplicationsAPI(APITestCase):
redirect_uris="http://some-other-domain",
authorization_flow=create_test_flow(),
)
self.allowed = Application.objects.create(
self.allowed: Application = Application.objects.create(
name="allowed",
slug="allowed",
meta_launch_url="https://goauthentik.io/%(username)s",
@ -35,6 +37,31 @@ class TestApplicationsAPI(APITestCase):
order=0,
)
def test_set_icon(self):
"""Test set_icon"""
file = ContentFile(b"text", "name")
self.client.force_login(self.user)
response = self.client.post(
reverse(
"authentik_api:application-set-icon",
kwargs={"slug": self.allowed.slug},
),
data=encode_multipart(data={"file": file}, boundary=BOUNDARY),
content_type=MULTIPART_CONTENT,
)
self.assertEqual(response.status_code, 200)
app_raw = self.client.get(
reverse(
"authentik_api:application-detail",
kwargs={"slug": self.allowed.slug},
),
)
app = loads(app_raw.content)
self.allowed.refresh_from_db()
self.assertEqual(self.allowed.get_meta_icon, app["meta_icon"])
self.assertEqual(self.allowed.meta_icon.read(), b"text")
def test_check_access(self):
"""Test check_access operation"""
self.client.force_login(self.user)

View File

@ -0,0 +1,69 @@
"""Test Groups API"""
from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Group, User
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id
class TestGroupsAPI(APITestCase):
"""Test Groups API"""
def setUp(self) -> None:
self.admin = create_test_admin_user()
self.user = User.objects.create(username="test-user")
def test_add_user(self):
"""Test add_user"""
group = Group.objects.create(name=generate_id())
self.client.force_login(self.admin)
res = self.client.post(
reverse("authentik_api:group-add-user", kwargs={"pk": group.pk}),
data={
"pk": self.user.pk,
},
)
self.assertEqual(res.status_code, 204)
group.refresh_from_db()
self.assertEqual(list(group.users.all()), [self.user])
def test_add_user_404(self):
"""Test add_user"""
group = Group.objects.create(name=generate_id())
self.client.force_login(self.admin)
res = self.client.post(
reverse("authentik_api:group-add-user", kwargs={"pk": group.pk}),
data={
"pk": self.user.pk + 3,
},
)
self.assertEqual(res.status_code, 404)
def test_remove_user(self):
"""Test remove_user"""
group = Group.objects.create(name=generate_id())
group.users.add(self.user)
self.client.force_login(self.admin)
res = self.client.post(
reverse("authentik_api:group-remove-user", kwargs={"pk": group.pk}),
data={
"pk": self.user.pk,
},
)
self.assertEqual(res.status_code, 204)
group.refresh_from_db()
self.assertEqual(list(group.users.all()), [])
def test_remove_user_404(self):
"""Test remove_user"""
group = Group.objects.create(name=generate_id())
group.users.add(self.user)
self.client.force_login(self.admin)
res = self.client.post(
reverse("authentik_api:group-remove-user", kwargs={"pk": group.pk}),
data={
"pk": self.user.pk + 3,
},
)
self.assertEqual(res.status_code, 404)

View File

@ -6,6 +6,8 @@ from django.shortcuts import get_object_or_404
from django.views.generic.base import TemplateView
from rest_framework.request import Request
from authentik import get_build_hash
from authentik.admin.tasks import LOCAL_VERSION
from authentik.api.v3.config import ConfigView
from authentik.flows.models import Flow
from authentik.tenants.api import CurrentTenantSerializer
@ -17,6 +19,9 @@ class InterfaceView(TemplateView):
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
kwargs["config_json"] = dumps(ConfigView(request=Request(self.request)).get_config().data)
kwargs["tenant_json"] = dumps(CurrentTenantSerializer(self.request.tenant).data)
kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"
kwargs["build"] = get_build_hash()
return super().get_context_data(**kwargs)

View File

@ -1,6 +1,7 @@
"""Events middleware"""
from functools import partial
from typing import Callable
from threading import Thread
from typing import Any, Callable, Optional
from django.conf import settings
from django.contrib.sessions.models import Session
@ -13,7 +14,6 @@ from guardian.models import UserObjectPermission
from authentik.core.models import AuthenticatedSession, User
from authentik.events.models import Event, EventAction, Notification
from authentik.events.signals import EventNewThread
from authentik.events.utils import model_to_dict
from authentik.flows.models import FlowToken
from authentik.lib.sentry import before_send
@ -37,6 +37,25 @@ def should_log_model(model: Model) -> bool:
return not isinstance(model, IGNORED_MODELS)
class EventNewThread(Thread):
"""Create Event in background thread"""
action: str
request: HttpRequest
kwargs: dict[str, Any]
user: Optional[User] = None
def __init__(self, action: str, request: HttpRequest, user: Optional[User] = None, **kwargs):
super().__init__()
self.action = action
self.request = request
self.user = user
self.kwargs = kwargs
def run(self):
Event.new(self.action, **self.kwargs).from_http(self.request, user=self.user)
class AuditMiddleware:
"""Register handlers for duration of request-response that log creation/update/deletion
of models"""

View File

@ -1,7 +1,6 @@
"""authentik events models"""
import time
from collections import Counter
from copy import deepcopy
from datetime import timedelta
from inspect import currentframe
from smtplib import SMTPException
@ -46,7 +45,7 @@ from authentik.stages.email.utils import TemplateEmailMessage
from authentik.tenants.models import Tenant
from authentik.tenants.utils import DEFAULT_TENANT
LOGGER = get_logger("authentik.events")
LOGGER = get_logger()
if TYPE_CHECKING:
from rest_framework.serializers import Serializer
@ -211,7 +210,7 @@ class Event(SerializerModel, ExpiringModel):
current = currentframe()
parent = current.f_back
app = parent.f_globals["__name__"]
cleaned_kwargs = cleanse_dict(sanitize_dict(deepcopy(kwargs)))
cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs))
event = Event(action=action, app=app, context=cleaned_kwargs)
return event

View File

@ -1,5 +1,4 @@
"""authentik events signal listener"""
from threading import Thread
from typing import Any, Optional
from django.contrib.auth.signals import user_logged_in, user_logged_out
@ -19,63 +18,40 @@ from authentik.stages.invitation.signals import invitation_used
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
from authentik.stages.user_write.signals import user_write
class EventNewThread(Thread):
"""Create Event in background thread"""
action: str
request: HttpRequest
kwargs: dict[str, Any]
user: Optional[User] = None
def __init__(self, action: str, request: HttpRequest, user: Optional[User] = None, **kwargs):
super().__init__()
self.action = action
self.request = request
self.user = user
self.kwargs = kwargs
def run(self):
Event.new(self.action, **self.kwargs).from_http(self.request, user=self.user)
SESSION_LOGIN_EVENT = "login_event"
@receiver(user_logged_in)
# pylint: disable=unused-argument
def on_user_logged_in(sender, request: HttpRequest, user: User, **_):
"""Log successful login"""
thread = EventNewThread(EventAction.LOGIN, request)
kwargs = {}
if SESSION_KEY_PLAN in request.session:
flow_plan: FlowPlan = request.session[SESSION_KEY_PLAN]
if PLAN_CONTEXT_SOURCE in flow_plan.context:
# Login request came from an external source, save it in the context
thread.kwargs[PLAN_CONTEXT_SOURCE] = flow_plan.context[PLAN_CONTEXT_SOURCE]
kwargs[PLAN_CONTEXT_SOURCE] = flow_plan.context[PLAN_CONTEXT_SOURCE]
if PLAN_CONTEXT_METHOD in flow_plan.context:
thread.kwargs[PLAN_CONTEXT_METHOD] = flow_plan.context[PLAN_CONTEXT_METHOD]
# Save the login method used
thread.kwargs[PLAN_CONTEXT_METHOD_ARGS] = flow_plan.context.get(
PLAN_CONTEXT_METHOD_ARGS, {}
)
thread.user = user
thread.run()
kwargs[PLAN_CONTEXT_METHOD] = flow_plan.context[PLAN_CONTEXT_METHOD]
kwargs[PLAN_CONTEXT_METHOD_ARGS] = flow_plan.context.get(PLAN_CONTEXT_METHOD_ARGS, {})
event = Event.new(EventAction.LOGIN, **kwargs).from_http(request, user=user)
request.session[SESSION_LOGIN_EVENT] = event
@receiver(user_logged_out)
# pylint: disable=unused-argument
def on_user_logged_out(sender, request: HttpRequest, user: User, **_):
"""Log successfully logout"""
thread = EventNewThread(EventAction.LOGOUT, request)
thread.user = user
thread.run()
Event.new(EventAction.LOGOUT).from_http(request, user=user)
@receiver(user_write)
# pylint: disable=unused-argument
def on_user_write(sender, request: HttpRequest, user: User, data: dict[str, Any], **kwargs):
"""Log User write"""
thread = EventNewThread(EventAction.USER_WRITE, request, **data)
thread.kwargs["created"] = kwargs.get("created", False)
thread.user = user
thread.run()
data["created"] = kwargs.get("created", False)
Event.new(EventAction.USER_WRITE, **data).from_http(request, user=user)
@receiver(login_failed)
@ -89,26 +65,23 @@ def on_login_failed(
**kwargs,
):
"""Failed Login, authentik custom event"""
thread = EventNewThread(EventAction.LOGIN_FAILED, request, **credentials, stage=stage, **kwargs)
thread.run()
Event.new(EventAction.LOGIN_FAILED, **credentials, stage=stage, **kwargs).from_http(request)
@receiver(invitation_used)
# pylint: disable=unused-argument
def on_invitation_used(sender, request: HttpRequest, invitation: Invitation, **_):
"""Log Invitation usage"""
thread = EventNewThread(
EventAction.INVITE_USED, request, invitation_uuid=invitation.invite_uuid.hex
Event.new(EventAction.INVITE_USED, invitation_uuid=invitation.invite_uuid.hex).from_http(
request
)
thread.run()
@receiver(password_changed)
# pylint: disable=unused-argument
def on_password_changed(sender, user: User, password: str, **_):
"""Log password change"""
thread = EventNewThread(EventAction.PASSWORD_SET, None, user=user)
thread.run()
Event.new(EventAction.PASSWORD_SET).from_http(None, user=user)
@receiver(post_save, sender=Event)

View File

@ -1,5 +1,6 @@
"""event utilities"""
import re
from copy import copy
from dataclasses import asdict, is_dataclass
from pathlib import Path
from types import GeneratorType
@ -87,9 +88,15 @@ def sanitize_item(value: Any) -> Any:
"""Sanitize a single item, ensure it is JSON parsable"""
if is_dataclass(value):
# Because asdict calls `copy.deepcopy(obj)` on everything that's not tuple/dict,
# and deepcopy doesn't work with HttpRequests (neither django nor rest_framework).
# and deepcopy doesn't work with HttpRequest (neither django nor rest_framework).
# (more specifically doesn't work with ResolverMatch)
# rest_framework's custom Request class makes this more complicated as it also holds a
# thread lock.
# Since this class is mainly used for Events which already hold the http request context
# we just remove the http_request from the shallow policy request
# Currently, the only dataclass that actually holds an http request is a PolicyRequest
if isinstance(value, PolicyRequest):
if isinstance(value, PolicyRequest) and value.http_request is not None:
value: PolicyRequest = copy(value)
value.http_request = None
value = asdict(value)
if isinstance(value, dict):

View File

@ -14,6 +14,7 @@ from authentik.core.models import Token
from authentik.core.types import UserSettingSerializer
from authentik.flows.challenge import FlowLayout
from authentik.lib.models import InheritanceForeignKey, SerializerModel
from authentik.lib.utils.reflection import class_to_path
from authentik.policies.models import PolicyBindingModel
if TYPE_CHECKING:
@ -110,6 +111,8 @@ def in_memory_stage(view: type["StageView"], **kwargs) -> Stage:
# we set the view as a separate property and reference a generic function
# that returns that member
setattr(stage, "__in_memory_type", view)
setattr(stage, "name", _("Dynamic In-memory stage: %(doc)s" % {"doc": view.__doc__}))
setattr(stage._meta, "verbose_name", class_to_path(view))
for key, value in kwargs.items():
setattr(stage, key, value)
return stage

View File

@ -378,7 +378,9 @@ class FlowExecutorView(APIView):
# an expression policy or authentik itself, so we don't
# check if its an absolute URL or a relative one
self.cancel()
return redirect(self.plan.context.get(PLAN_CONTEXT_REDIRECT))
return to_stage_response(
self.request, redirect(self.plan.context.get(PLAN_CONTEXT_REDIRECT))
)
next_param = self.request.session.get(SESSION_KEY_GET, {}).get(
NEXT_ARG_NAME, "authentik_core:root-redirect"
)

View File

@ -29,10 +29,9 @@ debug: false
log_level: info
# Error reporting, sends stacktrace to sentry.beryju.org
error_reporting:
enabled: false
sentry_dsn: https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8
sentry_dsn: https://151ba72610234c4c97c5bcff4e1cffd8@o4504163616882688.ingest.sentry.io/4504163677503489
environment: customer
send_pii: false
sample_rate: 0.1

View File

@ -42,7 +42,7 @@ class BaseEvaluator:
"ak_user_by": BaseEvaluator.expr_user_by,
"ak_user_has_authenticator": BaseEvaluator.expr_func_user_has_authenticator,
"ak_create_event": self.expr_event_create,
"ak_logger": get_logger(self._filename),
"ak_logger": get_logger(self._filename).bind(),
"requests": get_http_session(),
"ip_address": ip_address,
"ip_network": ip_network,

View File

@ -66,6 +66,9 @@ def sentry_init(**sentry_init_kwargs):
kwargs = {
"environment": sentry_env,
"send_default_pii": CONFIG.y_bool("error_reporting.send_pii", False),
"_experiments": {
"profiles_sample_rate": float(CONFIG.y("error_reporting.sample_rate", 0.1)),
},
}
kwargs.update(**sentry_init_kwargs)
# pylint: disable=abstract-class-instantiated

View File

@ -24,17 +24,17 @@ class FilePathSerializer(PassiveSerializer):
url = CharField()
def set_file(request: Request, obj: Model, field: str):
def set_file(request: Request, obj: Model, field_name: str):
"""Upload file"""
field = getattr(obj, field)
icon = request.FILES.get("file", None)
field = getattr(obj, field_name)
file = request.FILES.get("file", None)
clear = request.data.get("clear", "false").lower() == "true"
if clear:
# .delete() saves the model by default
field.delete()
return Response({})
if icon:
field = icon
if file:
setattr(obj, field_name, file)
try:
obj.save()
except PermissionError as exc:

View File

@ -87,7 +87,7 @@ class PolicyEvaluator(BaseEvaluator):
LOGGER.warning(
"Expression policy returned None",
src=expression_source,
req=self._context,
policy=self._filename,
)
policy_result.passing = False
if result:

View File

@ -0,0 +1,19 @@
# Generated by Django 4.1.4 on 2022-12-25 13:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_policies", "0008_policybinding_authentik_p_policy__534e15_idx_and_more"),
]
operations = [
migrations.AlterField(
model_name="policy",
name="name",
field=models.TextField(default="unnamed-policy"),
preserve_default=False,
),
]

View File

@ -159,7 +159,7 @@ class Policy(SerializerModel, CreatedUpdatedModel):
policy_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
name = models.TextField(blank=True, null=True)
name = models.TextField()
execution_logging = models.BooleanField(
default=False,

View File

@ -150,6 +150,8 @@ class PasswordPolicy(Policy):
results = zxcvbn(password[:100], user_inputs)
LOGGER.debug("password failed", check="zxcvbn", score=results["score"])
result = PolicyResult(results["score"] > self.zxcvbn_score_threshold)
if not result.passing:
result.messages += tuple((_("Password is too weak."),))
if isinstance(results["feedback"]["warning"], list):
result.messages += tuple(results["feedback"]["warning"])
if isinstance(results["feedback"]["suggestions"], list):

View File

@ -28,13 +28,21 @@ class TestPasswordPolicyZxcvbn(TestCase):
policy = PasswordPolicy.objects.create(
check_zxcvbn=True,
check_static_rules=False,
zxcvbn_score_threshold=3,
name="test_false",
)
request = PolicyRequest(get_anonymous_user())
request.context[PLAN_CONTEXT_PROMPT] = {"password": "password"} # nosec
result: PolicyResult = policy.passes(request)
self.assertFalse(result.passing, result.messages)
self.assertEqual(result.messages[0], "Add another word or two. Uncommon words are better.")
self.assertEqual(result.messages[0], "Password is too weak.")
self.assertEqual(result.messages[1], "Add another word or two. Uncommon words are better.")
request.context[PLAN_CONTEXT_PROMPT] = {"password": "Awdccdw1234"} # nosec
result: PolicyResult = policy.passes(request)
self.assertFalse(result.passing, result.messages)
self.assertEqual(result.messages[0], "Password is too weak.")
self.assertEqual(len(result.messages), 1)
def test_true(self):
"""Positive password case"""

View File

@ -101,12 +101,14 @@ class PolicyProcess(PROCESS_CLASS):
LOGGER.debug("P_ENG(proc): error", exc=src_exc)
policy_result = PolicyResult(False, str(src_exc))
policy_result.source_binding = self.binding
if self.request.should_cache:
should_cache = self.request.should_cache
if should_cache:
key = cache_key(self.binding, self.request)
cache.set(key, policy_result, CACHE_TIMEOUT)
LOGGER.debug(
"P_ENG(proc): finished and cached ",
"P_ENG(proc): finished",
policy=self.binding.policy,
cached=should_cache,
result=policy_result,
# this is used for filtering in access checking where logs are sent to the admin
process="PolicyProcess",

View File

@ -2,6 +2,7 @@
from django.contrib.auth.models import AnonymousUser
from django.core.cache import cache
from django.test import RequestFactory, TestCase
from django.urls import resolve, reverse
from guardian.shortcuts import get_anonymous_user
from authentik.core.models import Application, Group, User
@ -129,8 +130,9 @@ class TestPolicyProcess(TestCase):
)
binding = PolicyBinding(policy=policy, target=Application.objects.create(name="test"))
http_request = self.factory.get("/")
http_request = self.factory.get(reverse("authentik_core:impersonate-end"))
http_request.user = self.user
http_request.resolver_match = resolve(reverse("authentik_core:impersonate-end"))
request = PolicyRequest(self.user)
request.set_http_request(http_request)

View File

@ -8,11 +8,12 @@ from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import PassiveSerializer, PropertyMappingPreviewSerializer
from authentik.core.models import Provider
from authentik.providers.oauth2.models import OAuth2Provider
from authentik.providers.oauth2.models import OAuth2Provider, RefreshToken, ScopeMapping
class OAuth2ProviderSerializer(ProviderSerializer):
@ -115,7 +116,7 @@ class OAuth2ProviderViewSet(UsedByMixin, ModelViewSet):
)
data["logout"] = request.build_absolute_uri(
reverse(
"authentik_core:if-session-end",
"authentik_providers_oauth2:end-session",
kwargs={"application_slug": provider.application.slug},
)
)
@ -128,3 +129,28 @@ class OAuth2ProviderViewSet(UsedByMixin, ModelViewSet):
except Provider.application.RelatedObjectDoesNotExist: # pylint: disable=no-member
pass
return Response(data)
@permission_required(
"authentik_providers_oauth2.view_oauth2provider",
)
@extend_schema(
responses={
200: PropertyMappingPreviewSerializer(),
400: OpenApiResponse(description="Bad request"),
},
)
@action(detail=True, methods=["GET"])
# pylint: disable=invalid-name, unused-argument
def preview_user(self, request: Request, pk: int) -> Response:
"""Preview user data for provider"""
provider: OAuth2Provider = self.get_object()
temp_token = RefreshToken()
temp_token.scope = ScopeMapping.objects.filter(provider=provider).values_list(
"scope_name", flat=True
)
temp_token.provider = provider
temp_token.user = request.user
serializer = PropertyMappingPreviewSerializer(
instance={"preview": temp_token.create_id_token(request.user, request).to_dict()}
)
return Response(serializer.data)

View File

@ -12,7 +12,7 @@ from rest_framework.viewsets import GenericViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
from authentik.providers.oauth2.api.providers import OAuth2ProviderSerializer
from authentik.providers.oauth2.models import AuthorizationCode, RefreshToken

View File

@ -31,3 +31,9 @@ SCOPE_GITHUB_USER_EMAIL = "user:email"
SCOPE_GITHUB_ORG_READ = "read:org"
ACR_AUTHENTIK_DEFAULT = "goauthentik.io/providers/oauth2/default"
# https://datatracker.ietf.org/doc/html/draft-ietf-oauth-amr-values-06#section-2
AMR_PASSWORD = "pwd" # nosec
AMR_MFA = "mfa"
AMR_OTP = "otp"
AMR_WEBAUTHN = "user"

View File

@ -4,12 +4,14 @@ import binascii
import json
from dataclasses import asdict, dataclass, field
from datetime import datetime, timedelta
from functools import cached_property
from hashlib import sha256
from typing import Any, Optional
from urllib.parse import urlparse, urlunparse
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES
from dacite.core import from_dict
from django.db import models
from django.http import HttpRequest
@ -20,14 +22,20 @@ from rest_framework.serializers import Serializer
from authentik.core.models import ExpiringModel, PropertyMapping, Provider, User
from authentik.crypto.models import CertificateKeyPair
from authentik.events.models import Event, EventAction
from authentik.events.utils import get_user
from authentik.events.models import Event
from authentik.events.signals import SESSION_LOGIN_EVENT
from authentik.lib.generators import generate_code_fixed_length, generate_id, generate_key
from authentik.lib.models import SerializerModel
from authentik.lib.utils.time import timedelta_string_validator
from authentik.providers.oauth2.apps import AuthentikProviderOAuth2Config
from authentik.providers.oauth2.constants import ACR_AUTHENTIK_DEFAULT
from authentik.providers.oauth2.constants import (
ACR_AUTHENTIK_DEFAULT,
AMR_MFA,
AMR_PASSWORD,
AMR_WEBAUTHN,
)
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
class ClientTypes(models.TextChoices):
@ -122,7 +130,7 @@ class ScopeMapping(PropertyMapping):
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.oauth2.api.scope import ScopeMappingSerializer
from authentik.providers.oauth2.api.scopes import ScopeMappingSerializer
return ScopeMappingSerializer
@ -253,7 +261,8 @@ class OAuth2Provider(Provider):
token.access_token = token.create_access_token(user, request)
return token
def get_jwt_key(self) -> tuple[str, str]:
@cached_property
def jwt_key(self) -> tuple[str | PRIVATE_KEY_TYPES, str]:
"""Get either the configured certificate or the client secret"""
if not self.signing_key:
# No Certificate at all, assume HS256
@ -261,9 +270,9 @@ class OAuth2Provider(Provider):
key: CertificateKeyPair = self.signing_key
private_key = key.private_key
if isinstance(private_key, RSAPrivateKey):
return key.key_data, JWTAlgorithms.RS256
return private_key, JWTAlgorithms.RS256
if isinstance(private_key, EllipticCurvePrivateKey):
return key.key_data, JWTAlgorithms.ES256
return private_key, JWTAlgorithms.ES256
raise Exception(f"Invalid private key type: {type(private_key)}")
def get_issuer(self, request: HttpRequest) -> Optional[str]:
@ -294,7 +303,7 @@ class OAuth2Provider(Provider):
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
from authentik.providers.oauth2.api.providers import OAuth2ProviderSerializer
return OAuth2ProviderSerializer
@ -306,10 +315,9 @@ class OAuth2Provider(Provider):
headers = {}
if self.signing_key:
headers["kid"] = self.signing_key.kid
key, alg = self.get_jwt_key()
key, alg = self.jwt_key
# If the provider does not have an RSA Key assigned, it was switched to Symmetric
self.refresh_from_db()
# pyright: reportGeneralTypeIssues=false
return encode(payload, key, algorithm=alg, headers=headers)
class Meta:
@ -392,6 +400,7 @@ class IDToken:
iat: Optional[int] = None
auth_time: Optional[int] = None
acr: Optional[str] = ACR_AUTHENTIK_DEFAULT
amr: Optional[list[str]] = None
c_hash: Optional[str] = None
nonce: Optional[str] = None
@ -466,6 +475,7 @@ class RefreshToken(SerializerModel, ExpiringModel, BaseGrantModel):
token["uid"] = generate_key()
return self.provider.encode(token)
# pylint: disable=too-many-locals
def create_id_token(self, user: User, request: HttpRequest) -> IDToken:
"""Creates the id_token.
See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken"""
@ -485,21 +495,27 @@ class RefreshToken(SerializerModel, ExpiringModel, BaseGrantModel):
f"selected: {self.provider.sub_mode}"
)
)
amr = []
# Convert datetimes into timestamps.
now = datetime.now()
iat_time = int(now.timestamp())
exp_time = int(self.expires.timestamp())
# We use the timestamp of the user's last successful login (EventAction.LOGIN) for auth_time
auth_event = (
Event.objects.filter(action=EventAction.LOGIN, user=get_user(user))
.order_by("-created")
.first()
)
# Fallback in case we can't find any login events
auth_time = now
if auth_event:
if SESSION_LOGIN_EVENT in request.session:
auth_event: Event = request.session[SESSION_LOGIN_EVENT]
auth_time = auth_event.created
# Also check which method was used for authentication
method = auth_event.context.get(PLAN_CONTEXT_METHOD, "")
method_args = auth_event.context.get(PLAN_CONTEXT_METHOD_ARGS, {})
if method == "password":
amr.append(AMR_PASSWORD)
if method == "auth_webauthn_pwl":
amr.append(AMR_WEBAUTHN)
if "mfa_devices" in method_args:
if len(amr) > 0:
amr.append(AMR_MFA)
auth_timestamp = int(auth_time.timestamp())

View File

@ -0,0 +1,47 @@
"""Test OAuth2 API"""
from json import loads
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.lib.generators import generate_id, generate_key
from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping
class TestAPI(APITestCase):
"""Test api view"""
@apply_blueprint("system/providers-oauth2.yaml")
def setUp(self) -> None:
self.provider: OAuth2Provider = OAuth2Provider.objects.create(
name="test",
client_id=generate_id(),
client_secret=generate_key(),
authorization_flow=create_test_flow(),
redirect_uris="http://testserver",
)
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()
self.client.force_login(self.user)
def test_preview(self):
"""Test Preview API Endpoint"""
response = self.client.get(
reverse("authentik_api:oauth2provider-preview-user", kwargs={"pk": self.provider.pk})
)
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())["preview"]
self.assertEqual(body["iss"], "http://testserver/application/o/test/")
def test_setup_urls(self):
"""Test Setup URLs API Endpoint"""
response = self.client.get(
reverse("authentik_api:oauth2provider-setup-urls", kwargs={"pk": self.provider.pk})
)
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())
self.assertEqual(body["issuer"], "http://testserver/application/o/test/")

View File

@ -143,7 +143,7 @@ class TestTokenClientCredentials(OAuthTestCase):
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())
self.assertEqual(body["token_type"], "bearer")
_, alg = self.provider.get_jwt_key()
_, alg = self.provider.jwt_key
jwt = decode(
body["access_token"],
key=self.provider.signing_key.public_key,

View File

@ -210,7 +210,7 @@ class TestTokenClientCredentialsJWTSource(OAuthTestCase):
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())
self.assertEqual(body["token_type"], "bearer")
_, alg = self.provider.get_jwt_key()
_, alg = self.provider.jwt_key
jwt = decode(
body["access_token"],
key=self.provider.signing_key.public_key,

View File

@ -29,7 +29,7 @@ class OAuthTestCase(TestCase):
def validate_jwt(self, token: RefreshToken, provider: OAuth2Provider) -> dict[str, Any]:
"""Validate that all required fields are set"""
key, alg = provider.get_jwt_key()
key, alg = provider.jwt_key
if alg != JWTAlgorithms.HS256:
key = provider.signing_key.public_key
jwt = decode(

View File

@ -38,7 +38,7 @@ class ProviderInfoView(View):
)
if SCOPE_OPENID not in scopes:
scopes.append(SCOPE_OPENID)
_, supported_alg = provider.get_jwt_key()
_, supported_alg = provider.jwt_key
return {
"issuer": provider.get_issuer(self.request),
"authorization_endpoint": self.request.build_absolute_uri(
@ -52,7 +52,7 @@ class ProviderInfoView(View):
),
"end_session_endpoint": self.request.build_absolute_uri(
reverse(
"authentik_core:if-session-end",
"authentik_providers_oauth2:end-session",
kwargs={"application_slug": provider.application.slug},
)
),

View File

View File

@ -0,0 +1,42 @@
"""SAML Property mappings API Views"""
from django_filters.filters import AllValuesMultipleFilter
from django_filters.filterset import FilterSet
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema_field
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.providers.saml.models import SAMLPropertyMapping
class SAMLPropertyMappingSerializer(PropertyMappingSerializer):
"""SAMLPropertyMapping Serializer"""
class Meta:
model = SAMLPropertyMapping
fields = PropertyMappingSerializer.Meta.fields + [
"saml_name",
"friendly_name",
]
class SAMLPropertyMappingFilter(FilterSet):
"""Filter for SAMLPropertyMapping"""
managed = extend_schema_field(OpenApiTypes.STR)(AllValuesMultipleFilter(field_name="managed"))
class Meta:
model = SAMLPropertyMapping
fields = "__all__"
class SAMLPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""SAMLPropertyMapping Viewset"""
queryset = SAMLPropertyMapping.objects.all()
serializer_class = SAMLPropertyMappingSerializer
filterset_class = SAMLPropertyMappingFilter
search_fields = ["name"]
ordering = ["name"]

View File

@ -7,15 +7,8 @@ from django.http.response import Http404, HttpResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django_filters.filters import AllValuesMultipleFilter
from django_filters.filterset import FilterSet
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import (
OpenApiParameter,
OpenApiResponse,
extend_schema,
extend_schema_field,
)
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.decorators import action
from rest_framework.fields import CharField, FileField, SerializerMethodField
from rest_framework.parsers import MultiPartParser
@ -28,15 +21,16 @@ from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger
from authentik.api.decorators import permission_required
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import PassiveSerializer, PropertyMappingPreviewSerializer
from authentik.core.models import Provider
from authentik.flows.models import Flow, FlowDesignation
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.models import SAMLProvider
from authentik.providers.saml.processors.assertion import AssertionProcessor
from authentik.providers.saml.processors.metadata import MetadataProcessor
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
from authentik.providers.saml.processors.request_parser import AuthNRequest
from authentik.sources.saml.processors.constants import SAML_BINDING_POST, SAML_BINDING_REDIRECT
LOGGER = get_logger()
@ -236,34 +230,31 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
)
return Response(status=204)
class SAMLPropertyMappingSerializer(PropertyMappingSerializer):
"""SAMLPropertyMapping Serializer"""
class Meta:
model = SAMLPropertyMapping
fields = PropertyMappingSerializer.Meta.fields + [
"saml_name",
"friendly_name",
]
class SAMLPropertyMappingFilter(FilterSet):
"""Filter for SAMLPropertyMapping"""
managed = extend_schema_field(OpenApiTypes.STR)(AllValuesMultipleFilter(field_name="managed"))
class Meta:
model = SAMLPropertyMapping
fields = "__all__"
class SAMLPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""SAMLPropertyMapping Viewset"""
queryset = SAMLPropertyMapping.objects.all()
serializer_class = SAMLPropertyMappingSerializer
filterset_class = SAMLPropertyMappingFilter
search_fields = ["name"]
ordering = ["name"]
@permission_required(
"authentik_providers_saml.view_samlprovider",
)
@extend_schema(
responses={
200: PropertyMappingPreviewSerializer(),
400: OpenApiResponse(description="Bad request"),
},
)
@action(detail=True, methods=["GET"])
# pylint: disable=invalid-name, unused-argument
def preview_user(self, request: Request, pk: int) -> Response:
"""Preview user data for provider"""
provider: SAMLProvider = self.get_object()
processor = AssertionProcessor(provider, request._request, AuthNRequest())
attributes = processor.get_attributes()
name_id = processor.get_name_id()
data = []
for attribute in attributes:
item = {"Value": []}
item.update(attribute.attrib)
for value in attribute:
item["Value"].append(value.text)
data.append(item)
serializer = PropertyMappingPreviewSerializer(
instance={"preview": {"attributes": data, "nameID": name_id.text}}
)
return Response(serializer.data)

View File

@ -164,7 +164,7 @@ class SAMLProvider(Provider):
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.saml.api import SAMLProviderSerializer
from authentik.providers.saml.api.providers import SAMLProviderSerializer
return SAMLProviderSerializer
@ -193,7 +193,7 @@ class SAMLPropertyMapping(PropertyMapping):
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.saml.api import SAMLPropertyMappingSerializer
from authentik.providers.saml.api.property_mapping import SAMLPropertyMappingSerializer
return SAMLPropertyMappingSerializer

View File

@ -10,6 +10,7 @@ from structlog.stdlib import get_logger
from authentik.core.exceptions import PropertyMappingExpressionException
from authentik.events.models import Event, EventAction
from authentik.events.signals import SESSION_LOGIN_EVENT
from authentik.lib.utils.time import timedelta_from_string
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.processors.request_parser import AuthNRequest
@ -30,6 +31,7 @@ from authentik.sources.saml.processors.constants import (
SAML_NAME_ID_FORMAT_X509,
SIGN_ALGORITHM_TRANSFORM_MAP,
)
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
LOGGER = get_logger()
@ -129,9 +131,23 @@ class AssertionProcessor:
auth_n_context_class_ref = SubElement(
auth_n_context, f"{{{NS_SAML_ASSERTION}}}AuthnContextClassRef"
)
auth_n_context_class_ref.text = (
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
)
auth_n_context_class_ref.text = "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"
if SESSION_LOGIN_EVENT in self.http_request.session:
event: Event = self.http_request.session[SESSION_LOGIN_EVENT]
method = event.context.get(PLAN_CONTEXT_METHOD, "")
method_args = event.context.get(PLAN_CONTEXT_METHOD_ARGS, {})
if method == "password":
auth_n_context_class_ref.text = (
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
)
if "mfa_devices" in method_args:
auth_n_context_class_ref.text = (
"urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract"
)
if method in ["auth_mfa", "auth_webauthn_pwl"]:
auth_n_context_class_ref.text = (
"urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract"
)
return auth_n_statement
def get_assertion_conditions(self) -> Element:

View File

@ -1,13 +1,15 @@
"""SAML Provider API Tests"""
from json import loads
from tempfile import TemporaryFile
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.models import FlowDesignation
from authentik.providers.saml.models import SAMLProvider
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.tests.test_metadata import METADATA_SIMPLE
@ -107,3 +109,24 @@ class TestSAMLProviderAPI(APITestCase):
format="multipart",
)
self.assertEqual(400, response.status_code)
@apply_blueprint("system/providers-saml.yaml")
def test_preview(self):
"""Test Preview API Endpoint"""
provider: SAMLProvider = SAMLProvider.objects.create(
name="test",
authorization_flow=create_test_flow(),
)
provider.property_mappings.set(SAMLPropertyMapping.objects.all())
Application.objects.create(name="test", provider=provider, slug="test")
response = self.client.get(
reverse("authentik_api:samlprovider-preview-user", kwargs={"pk": provider.pk})
)
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())["preview"]["attributes"]
self.assertEqual(
[x for x in body if x["Name"] == "http://schemas.goauthentik.io/2021/02/saml/username"][
0
]["Value"],
[self.user.username],
)

View File

@ -452,22 +452,29 @@ _DISALLOWED_ITEMS = [
"AUTHENTICATION_BACKENDS",
"CELERY_BEAT_SCHEDULE",
]
# Load subapps's INSTALLED_APPS
def _update_settings(app_path: str):
try:
settings_module = importlib.import_module(app_path)
CONFIG.log("debug", "Loaded app settings", path=app_path)
INSTALLED_APPS.extend(getattr(settings_module, "INSTALLED_APPS", []))
MIDDLEWARE.extend(getattr(settings_module, "MIDDLEWARE", []))
AUTHENTICATION_BACKENDS.extend(getattr(settings_module, "AUTHENTICATION_BACKENDS", []))
CELERY_BEAT_SCHEDULE.update(getattr(settings_module, "CELERY_BEAT_SCHEDULE", {}))
for _attr in dir(settings_module):
if not _attr.startswith("__") and _attr not in _DISALLOWED_ITEMS:
globals()[_attr] = getattr(settings_module, _attr)
except ImportError:
pass
# Load subapps's settings
for _app in INSTALLED_APPS:
if _app.startswith("authentik"):
if "apps" in _app:
_app = ".".join(_app.split(".")[:-2])
try:
app_settings = importlib.import_module(f"{_app}.settings")
INSTALLED_APPS.extend(getattr(app_settings, "INSTALLED_APPS", []))
MIDDLEWARE.extend(getattr(app_settings, "MIDDLEWARE", []))
AUTHENTICATION_BACKENDS.extend(getattr(app_settings, "AUTHENTICATION_BACKENDS", []))
CELERY_BEAT_SCHEDULE.update(getattr(app_settings, "CELERY_BEAT_SCHEDULE", {}))
for _attr in dir(app_settings):
if not _attr.startswith("__") and _attr not in _DISALLOWED_ITEMS:
globals()[_attr] = getattr(app_settings, _attr)
except ImportError:
pass
if not _app.startswith("authentik"):
continue
_update_settings(f"{_app}.settings")
_update_settings("data.user_settings")
if DEBUG:
CELERY_TASK_ALWAYS_EAGER = True

View File

@ -34,7 +34,7 @@ class PytestTestRunner: # pragma: no cover
"outposts.container_image_base",
f"ghcr.io/goauthentik/dev-%(type)s:{get_docker_tag()}",
)
CONFIG.y_set("error_reporting.sample_rate", 1.0)
CONFIG.y_set("error_reporting.sample_rate", 0)
sentry_init(
environment="testing",
send_default_pii=True,

View File

@ -8,7 +8,7 @@ from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import SourceSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.providers.saml.api import SAMLMetadataSerializer
from authentik.providers.saml.api.providers import SAMLMetadataSerializer
from authentik.sources.saml.models import SAMLSource
from authentik.sources.saml.processors.metadata import MetadataProcessor

View File

@ -128,6 +128,7 @@ class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
duo_user_id=request.data.get("duo_user_id"),
user=user,
stage=stage,
confirmed=True,
name="Imported Duo Authenticator",
)
return Response(status=204)

View File

@ -13,14 +13,15 @@ class AuthenticatorValidateStageSerializer(StageSerializer):
def validate_not_configured_action(self, value):
"""Ensure that a configuration stage is set when not_configured_action is configure"""
configuration_stages = self.initial_data.get("configuration_stages")
if value == NotConfiguredAction.CONFIGURE and configuration_stages is None:
raise ValidationError(
(
'When "Not configured action" is set to "Configure", '
"you must set a configuration stage."
configuration_stages = self.initial_data.get("configuration_stages", None)
if value == NotConfiguredAction.CONFIGURE:
if not configuration_stages or len(configuration_stages) < 1:
raise ValidationError(
(
'When "Not configured action" is set to "Configure", '
"you must set a configuration stage."
)
)
)
return value
class Meta:

View File

@ -200,15 +200,16 @@ def validate_challenge_duo(device_pk: int, stage_view: StageView, user: User) ->
)
# {'result': 'allow', 'status': 'allow', 'status_msg': 'Success. Logging you in...'}
if response["result"] == "deny":
LOGGER.debug("duo push response", result=response["result"], msg=response["status_msg"])
login_failed.send(
sender=__name__,
credentials={"username": user.username},
request=stage_view.request,
stage=stage_view.executor.current_stage,
device_class=DeviceClasses.DUO.value,
duo_response=response,
)
raise ValidationError("Duo denied access")
device.save()
raise ValidationError("Duo denied access", code="denied")
return device
except RuntimeError as exc:
Event.new(
@ -216,4 +217,4 @@ def validate_challenge_duo(device_pk: int, stage_view: StageView, user: User) ->
message=f"Failed to DUO authenticate user: {str(exc)}",
user=user,
).from_http(stage_view.request, user)
raise ValidationError("Duo denied access")
raise ValidationError("Duo denied access", code="denied")

View File

@ -134,6 +134,12 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
# Here we only check if the any data was sent at all
if "code" not in attrs and "webauthn" not in attrs and "duo" not in attrs:
raise ValidationError("Empty response")
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD, "auth_mfa")
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD_ARGS, {})
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS].setdefault("mfa_devices", [])
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS]["mfa_devices"].append(
self.device
)
return attrs

View File

@ -3,17 +3,22 @@ from unittest.mock import MagicMock, patch
from django.contrib.sessions.middleware import SessionMiddleware
from django.test.client import RequestFactory
from django.urls import reverse
from rest_framework.exceptions import ValidationError
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.planner import FlowPlan
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.events.models import Event, EventAction
from authentik.flows.models import FlowDesignation, FlowStageBinding
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from authentik.flows.stage import StageView
from authentik.flows.tests import FlowTestCase
from authentik.flows.views.executor import FlowExecutorView
from authentik.flows.views.executor import SESSION_KEY_PLAN, FlowExecutorView
from authentik.lib.generators import generate_id, generate_key
from authentik.lib.tests.utils import dummy_get_response
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
from authentik.stages.authenticator_validate.challenge import validate_challenge_duo
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage, DeviceClasses
from authentik.stages.user_login.models import UserLoginStage
from authentik.tenants.utils import get_tenant_for_request
@ -73,7 +78,17 @@ class AuthenticatorValidateStageDuoTests(FlowTestCase):
)
with patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.auth_client",
MagicMock(return_value=MagicMock(auth=MagicMock(return_value={"result": "deny"}))),
MagicMock(
return_value=MagicMock(
auth=MagicMock(
return_value={
"result": "deny",
"status": "deny",
"status_msg": "foo",
}
)
)
),
):
with self.assertRaises(ValidationError):
validate_challenge_duo(
@ -87,3 +102,88 @@ class AuthenticatorValidateStageDuoTests(FlowTestCase):
),
self.user,
)
@patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.auth_client",
MagicMock(
return_value=MagicMock(
auth=MagicMock(
return_value={
"result": "allow",
"status": "allow",
"status_msg": "Success. Logging you in...",
}
)
)
),
)
def test_full(self):
"""Test full within a flow executor"""
duo_stage = AuthenticatorDuoStage.objects.create(
name=generate_id(),
client_id=generate_id(),
client_secret=generate_key(),
api_hostname="",
)
duo_device = DuoDevice.objects.create(
user=self.user,
stage=duo_stage,
)
flow = create_test_flow(FlowDesignation.AUTHENTICATION)
stage = AuthenticatorValidateStage.objects.create(
name=generate_id(),
device_classes=[DeviceClasses.DUO],
)
plan = FlowPlan(flow_pk=flow.pk.hex)
plan.append(FlowStageBinding.objects.create(target=flow, stage=stage, order=2))
plan.append(
FlowStageBinding.objects.create(
target=flow, stage=UserLoginStage.objects.create(name=generate_id()), order=3
)
)
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
self.assertEqual(response.status_code, 200)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"duo": duo_device.pk},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
event = Event.objects.filter(
action=EventAction.LOGIN,
user__pk=self.user.pk,
).first()
self.assertIsNotNone(event)
self.assertEqual(
event.context,
{
"auth_method": "auth_mfa",
"auth_method_args": {
"mfa_devices": [
{
"app": "authentik_stages_authenticator_duo",
"model_name": "duodevice",
"name": "",
"pk": duo_device.pk,
}
]
},
"http_request": {
"args": {},
"method": "GET",
"path": f"/api/v3/flows/executor/{flow.slug}/",
},
},
)

View File

@ -68,7 +68,10 @@ class AuthenticatorValidateStageTests(FlowTestCase):
"""Test serializer validation"""
self.client.force_login(self.user)
serializer = AuthenticatorValidateStageSerializer(
data={"name": generate_id(), "not_configured_action": NotConfiguredAction.CONFIGURE}
data={
"name": generate_id(),
"not_configured_action": NotConfiguredAction.CONFIGURE,
}
)
self.assertFalse(serializer.is_valid())
self.assertIn("not_configured_action", serializer.errors)

View File

@ -12,7 +12,7 @@ class CaptchaStageSerializer(StageSerializer):
class Meta:
model = CaptchaStage
fields = StageSerializer.Meta.fields + ["public_key", "private_key"]
fields = StageSerializer.Meta.fields + ["public_key", "private_key", "js_url", "api_url"]
extra_kwargs = {"private_key": {"write_only": True}}

View File

@ -0,0 +1,33 @@
# Generated by Django 4.1.2 on 2022-10-20 19:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_captcha", "0001_initial"),
]
operations = [
migrations.AddField(
model_name="captchastage",
name="api_url",
field=models.TextField(default="https://www.recaptcha.net/recaptcha/api/siteverify"),
),
migrations.AddField(
model_name="captchastage",
name="js_url",
field=models.TextField(default="https://www.recaptcha.net/recaptcha/api.js"),
),
migrations.AlterField(
model_name="captchastage",
name="private_key",
field=models.TextField(help_text="Private key, acquired your captcha Provider."),
),
migrations.AlterField(
model_name="captchastage",
name="public_key",
field=models.TextField(help_text="Public key, acquired your captcha Provider."),
),
]

View File

@ -11,12 +11,11 @@ from authentik.flows.models import Stage
class CaptchaStage(Stage):
"""Verify the user is human using Google's reCaptcha."""
public_key = models.TextField(
help_text=_("Public key, acquired from https://www.google.com/recaptcha/intro/v3.html")
)
private_key = models.TextField(
help_text=_("Private key, acquired from https://www.google.com/recaptcha/intro/v3.html")
)
public_key = models.TextField(help_text=_("Public key, acquired your captcha Provider."))
private_key = models.TextField(help_text=_("Private key, acquired your captcha Provider."))
js_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api.js")
api_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api/siteverify")
@property
def serializer(self) -> type[BaseSerializer]:

View File

@ -20,6 +20,7 @@ class CaptchaChallenge(WithUserInfoChallenge):
"""Site public key"""
site_key = CharField()
js_url = CharField(read_only=True)
component = CharField(default="ak-stage-captcha")
@ -34,7 +35,7 @@ class CaptchaChallengeResponse(ChallengeResponse):
stage: CaptchaStage = self.stage.executor.current_stage
try:
response = get_http_session().post(
"https://www.google.com/recaptcha/api/siteverify",
stage.api_url,
headers={
"Content-type": "application/x-www-form-urlencoded",
},
@ -61,6 +62,7 @@ class CaptchaStageView(ChallengeStageView):
def get_challenge(self, *args, **kwargs) -> Challenge:
return CaptchaChallenge(
data={
"js_url": self.executor.current_stage.js_url,
"type": ChallengeTypes.NATIVE.value,
"site_key": self.executor.current_stage.public_key,
}

View File

@ -8,6 +8,7 @@ from rest_framework.viewsets import ModelViewSet
from authentik.core.api.groups import GroupMemberSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import is_dict
from authentik.flows.api.flows import FlowSerializer
from authentik.flows.api.stages import StageSerializer
from authentik.stages.invitation.models import Invitation, InvitationStage
@ -49,6 +50,7 @@ class InvitationSerializer(ModelSerializer):
created_by = GroupMemberSerializer(read_only=True)
fixed_data = JSONField(validators=[is_dict], required=False)
flow_obj = FlowSerializer(read_only=True, required=False, source="flow")
class Meta:
@ -60,6 +62,8 @@ class InvitationSerializer(ModelSerializer):
"fixed_data",
"created_by",
"single_use",
"flow",
"flow_obj",
]
@ -69,8 +73,8 @@ class InvitationViewSet(UsedByMixin, ModelViewSet):
queryset = Invitation.objects.all()
serializer_class = InvitationSerializer
ordering = ["-expires"]
search_fields = ["name", "created_by__username", "expires"]
filterset_fields = ["name", "created_by__username", "expires"]
search_fields = ["name", "created_by__username", "expires", "flow__slug"]
filterset_fields = ["name", "created_by__username", "expires", "flow__slug"]
def perform_create(self, serializer: InvitationSerializer):
serializer.save(created_by=self.request.user)

View File

@ -0,0 +1,26 @@
# Generated by Django 4.1.4 on 2022-12-20 13:43
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_flows", "0024_flow_authentication"),
("authentik_stages_invitation", "0001_squashed_0006_invitation_name"),
]
operations = [
migrations.AddField(
model_name="invitation",
name="flow",
field=models.ForeignKey(
default=None,
help_text="When set, only the configured flow can use this invitation.",
null=True,
on_delete=django.db.models.deletion.SET_DEFAULT,
to="authentik_flows.flow",
),
),
]

View File

@ -55,6 +55,13 @@ class Invitation(SerializerModel, ExpiringModel):
name = models.SlugField()
flow = models.ForeignKey(
"authentik_flows.Flow",
default=None,
null=True,
on_delete=models.SET_DEFAULT,
help_text=_("When set, only the configured flow can use this invitation."),
)
single_use = models.BooleanField(
default=False,
help_text=_("When enabled, the invitation will be deleted after usage."),

View File

@ -3,6 +3,7 @@ from typing import Optional
from deepmerge import always_merger
from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext_lazy as _
from authentik.flows.stage import StageView
from authentik.flows.views.executor import SESSION_KEY_GET
@ -35,22 +36,30 @@ class InvitationStageView(StageView):
return self.executor.plan.context[PLAN_CONTEXT_PROMPT][INVITATION_TOKEN_KEY_CONTEXT]
return None
def get(self, request: HttpRequest) -> HttpResponse:
"""Apply data to the current flow based on a URL"""
stage: InvitationStage = self.executor.current_stage
def get_invite(self) -> Optional[Invitation]:
"""Check the token, find the invite and check it's flow"""
token = self.get_token()
if not token:
# No Invitation was given, raise error or continue
if stage.continue_flow_without_invitation:
return self.executor.stage_ok()
return self.executor.stage_invalid()
return None
invite: Invitation = Invitation.objects.filter(pk=token).first()
if not invite:
self.logger.debug("invalid invitation", token=token)
return None
if invite.flow and invite.flow.pk.hex != self.executor.plan.flow_pk:
self.logger.debug("invite for incorrect flow", expected=invite.flow.slug)
return None
return invite
def get(self, request: HttpRequest) -> HttpResponse:
"""Apply data to the current flow based on a URL"""
stage: InvitationStage = self.executor.current_stage
invite = self.get_invite()
if not invite:
if stage.continue_flow_without_invitation:
return self.executor.stage_ok()
return self.executor.stage_invalid()
return self.executor.stage_invalid(_("Invalid invite/invite not found"))
self.executor.plan.context[INVITATION_IN_EFFECT] = True
self.executor.plan.context[INVITATION] = invite

View File

@ -23,7 +23,7 @@ from authentik.stages.password import BACKEND_INBUILT
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
class TestUserLoginStage(FlowTestCase):
class TestInvitationStage(FlowTestCase):
"""Login tests"""
def setUp(self):
@ -98,6 +98,33 @@ class TestUserLoginStage(FlowTestCase):
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
def test_invalid_flow(self):
"""Test with invitation, invalid flow limit"""
invalid_flow = create_test_flow(FlowDesignation.ENROLLMENT)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
data = {"foo": "bar"}
invite = Invitation.objects.create(
created_by=get_anonymous_user(), fixed_data=data, flow=invalid_flow
)
with patch("authentik.flows.views.executor.FlowExecutorView.cancel", MagicMock()):
base_url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
args = urlencode({INVITATION_TOKEN_KEY: invite.pk.hex})
response = self.client.get(base_url + f"?query={args}")
session = self.client.session
plan: FlowPlan = session[SESSION_KEY_PLAN]
self.assertStageResponse(
response,
flow=self.flow,
component="ak-stage-access-denied",
)
def test_with_invitation_prompt_data(self):
"""Test with invitation, check data in session"""
data = {"foo": "bar"}

View File

@ -11,6 +11,7 @@ from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from authentik.flows.tests import FlowTestCase
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.generators import generate_id
from authentik.stages.password import BACKEND_INBUILT
from authentik.stages.password.models import PasswordStage
@ -25,7 +26,7 @@ class TestPasswordStage(FlowTestCase):
self.user = create_test_admin_user()
self.flow = create_test_flow(FlowDesignation.AUTHENTICATION)
self.stage = PasswordStage.objects.create(name="password", backends=[BACKEND_INBUILT])
self.stage = PasswordStage.objects.create(name=generate_id(), backends=[BACKEND_INBUILT])
self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)
@patch(

View File

@ -5,7 +5,7 @@ from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _
from authentik.core.models import User
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE
from authentik.flows.stage import StageView
from authentik.lib.utils.time import timedelta_from_string
from authentik.stages.password import BACKEND_INBUILT
@ -52,5 +52,8 @@ class UserLoginStageView(StageView):
session_duration=self.executor.current_stage.session_duration,
)
self.request.session[USER_LOGIN_AUTHENTICATED] = True
messages.success(self.request, _("Successfully logged in!"))
# Only show success message if we don't have a source in the flow
# as sources show their own success messages
if not self.executor.plan.context.get(PLAN_CONTEXT_SOURCE, None):
messages.success(self.request, _("Successfully logged in!"))
return self.executor.stage_ok()

View File

@ -15,6 +15,7 @@ class UserWriteStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields + [
"create_users_as_inactive",
"create_users_group",
"can_create_users",
"user_path_template",
]

View File

@ -0,0 +1,21 @@
# Generated by Django 4.1.4 on 2022-12-22 14:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_user_write", "0005_userwritestage_user_path_template"),
]
operations = [
migrations.AddField(
model_name="userwritestage",
name="can_create_users",
field=models.BooleanField(
default=True,
help_text="When set, this stage can create users. If not enabled and no user is available, stage will fail.",
),
),
]

View File

@ -13,6 +13,16 @@ class UserWriteStage(Stage):
"""Writes currently pending data into the pending user, or if no user exists,
creates a new user with the data."""
can_create_users = models.BooleanField(
default=True,
help_text=_(
(
"When set, this stage can create users. "
"If not enabled and no user is available, stage will fail."
)
),
)
create_users_as_inactive = models.BooleanField(
default=False,
help_text=_("When set, newly created users are inactive and cannot login."),

View File

@ -1,10 +1,9 @@
"""Write stage logic"""
from typing import Any
from typing import Any, Optional
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
from django.db import transaction
from django.db.utils import IntegrityError
from django.db.utils import IntegrityError, InternalError
from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _
@ -47,7 +46,7 @@ class UserWriteStageView(StageView):
"""Wrapper for post requests"""
return self.get(request)
def ensure_user(self) -> tuple[User, bool]:
def ensure_user(self) -> tuple[Optional[User], bool]:
"""Ensure a user exists"""
user_created = False
path = self.executor.plan.context.get(
@ -55,7 +54,11 @@ class UserWriteStageView(StageView):
)
if path == "":
path = User.default_path()
if not self.request.user.is_anonymous:
self.executor.plan.context.setdefault(PLAN_CONTEXT_PENDING_USER, self.request.user)
if PLAN_CONTEXT_PENDING_USER not in self.executor.plan.context:
if not self.executor.current_stage.can_create_users:
return None, False
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = User(
is_active=not self.executor.current_stage.create_users_as_inactive,
path=path,
@ -73,7 +76,9 @@ class UserWriteStageView(StageView):
"""Update `user` with data from plan context
Only simple attributes are updated, nothing which requires a foreign key or m2m"""
data = self.executor.plan.context[PLAN_CONTEXT_PROMPT]
data: dict = self.executor.plan.context[PLAN_CONTEXT_PROMPT]
# This is always sent back but not written to the user
data.pop("component", None)
for key, value in data.items():
setter_name = f"set_{key}"
# Check if user has a setter for this key, like set_password
@ -110,11 +115,14 @@ class UserWriteStageView(StageView):
a new user is created."""
if PLAN_CONTEXT_PROMPT not in self.executor.plan.context:
message = _("No Pending data.")
messages.error(request, message)
self.logger.debug(message)
return self.executor.stage_invalid()
return self.executor.stage_invalid(message)
data = self.executor.plan.context[PLAN_CONTEXT_PROMPT]
user, user_created = self.ensure_user()
if not user:
message = _("No user found and can't create new user.")
self.logger.info(message)
return self.executor.stage_invalid(message)
# Before we change anything, check if the user is the same as in the request
# and we're updating a password. In that case we need to update the session hash
# Also check that we're not currently impersonating, so we don't update the session
@ -137,9 +145,9 @@ class UserWriteStageView(StageView):
user.ak_groups.add(self.executor.current_stage.create_users_group)
if PLAN_CONTEXT_GROUPS in self.executor.plan.context:
user.ak_groups.add(*self.executor.plan.context[PLAN_CONTEXT_GROUPS])
except (IntegrityError, ValueError, TypeError) as exc:
except (IntegrityError, ValueError, TypeError, InternalError) as exc:
self.logger.warning("Failed to save user", exc=exc)
return self.executor.stage_invalid()
return self.executor.stage_invalid(_("Failed to save user"))
user_write.send(sender=self, request=request, user=user, data=data, created=user_created)
# Check if the password has been updated, and update the session auth hash
if should_update_session:

View File

@ -1,6 +1,4 @@
"""write tests"""
import string
from random import SystemRandom
from unittest.mock import patch
from django.urls import reverse
@ -14,6 +12,7 @@ from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from authentik.flows.tests import FlowTestCase
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.generators import generate_key
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
from authentik.stages.user_write.models import UserWriteStage
from authentik.stages.user_write.stage import PLAN_CONTEXT_GROUPS, UserWriteStageView
@ -32,12 +31,11 @@ class TestUserWriteStage(FlowTestCase):
)
self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)
self.source = Source.objects.create(name="fake_source")
self.user = create_test_admin_user()
def test_user_create(self):
"""Test creation of user"""
password = "".join(
SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(8)
)
password = generate_key()
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
plan.context[PLAN_CONTEXT_PROMPT] = {
@ -66,9 +64,7 @@ class TestUserWriteStage(FlowTestCase):
def test_user_update(self):
"""Test update of existing user"""
new_password = "".join(
SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(8)
)
new_password = generate_key()
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
plan.context[PLAN_CONTEXT_PENDING_USER] = User.objects.create(
username="unittest", email="test@goauthentik.io"
@ -142,6 +138,49 @@ class TestUserWriteStage(FlowTestCase):
component="ak-stage-access-denied",
)
def test_authenticated_no_user(self):
"""Test user in session and none in plan"""
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
self.client.force_login(self.user)
session = self.client.session
plan.context[PLAN_CONTEXT_PROMPT] = {
"username": "foo",
"attribute_some-custom-attribute": "test",
"some_ignored_attribute": "bar",
}
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
self.user.refresh_from_db()
self.assertEqual(self.user.username, "foo")
def test_no_create(self):
"""Test can_create_users set to false"""
self.stage.can_create_users = False
self.stage.save()
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
plan.context[PLAN_CONTEXT_PROMPT] = {
"username": "foo",
"attribute_some-custom-attribute": "test",
"some_ignored_attribute": "bar",
}
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertStageResponse(
response,
self.flow,
component="ak-stage-access-denied",
)
@patch(
"authentik.flows.views.executor.to_stage_response",
TO_STAGE_RESPONSE_MOCK,

View File

@ -45,6 +45,8 @@ entries:
name: default-password-change-write
id: default-password-change-write
model: authentik_stages_user_write.userwritestage
attrs:
can_create_users: false
- identifiers:
order: 0
stage: !KeyOf default-password-change-prompt

View File

@ -6,7 +6,7 @@ entries:
designation: invalidation
name: Logout
title: Default Invalidation Flow
authentication: require_authenticated
authentication: none
identifiers:
slug: default-invalidation-flow
model: authentik_flows.flow

View File

@ -57,6 +57,8 @@ entries:
name: default-source-enrollment-write
id: default-source-enrollment-write
model: authentik_stages_user_write.userwritestage
attrs:
can_create_users: true
- attrs:
re_evaluate_policies: true
identifiers:

View File

@ -109,6 +109,8 @@ entries:
model: authentik_policies_expression.expressionpolicy
- identifiers:
name: default-user-settings-write
attrs:
can_create_users: false
id: default-user-settings-write
model: authentik_stages_user_write.userwritestage
- attrs:

View File

@ -102,6 +102,8 @@ entries:
identifiers:
name: default-password-change-write
model: authentik_stages_user_write.userwritestage
attrs:
can_create_users: false
- attrs:
evaluate_on_plan: true
invalid_response_action: retry

View File

@ -95,7 +95,8 @@ entries:
name: default-enrollment-user-write
id: default-enrollment-user-write
model: authentik_stages_user_write.userwritestage
attrs: {}
attrs:
can_create_users: true
- identifiers:
target: !KeyOf flow
stage: !KeyOf default-enrollment-prompt-first

View File

@ -114,6 +114,7 @@ entries:
model: authentik_stages_user_write.userwritestage
attrs:
create_users_as_inactive: true
can_create_users: true
- identifiers:
target: !KeyOf flow
stage: !KeyOf default-enrollment-prompt-first

View File

@ -63,6 +63,8 @@ entries:
name: default-recovery-user-write
id: default-recovery-user-write
model: authentik_stages_user_write.userwritestage
attrs:
can_create_users: false
- identifiers:
name: default-recovery-identification
id: default-recovery-identification

View File

@ -130,6 +130,12 @@
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"attrs": {
"type": "object",
"properties": {

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