Compare commits

...

442 Commits

Author SHA1 Message Date
80eb56b016 Merge branch 'main' into celery-2-dramatiq 2025-07-01 11:05:56 +02:00
3a1d0fbd35 try fixing package in docker
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-07-01 11:05:36 +02:00
c85471575a stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#15327)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-07-01 10:40:19 +02:00
5d00dc7e9e enterprise/search: fix search fallback for non QL queries (#15325)
* enterprise/search: fix search fallback for non QL queries

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix fixed tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-07-01 00:55:23 +02:00
6982e7d1c9 web/elements: fix table search not resetting page when query changes (#15324)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-07-01 00:55:09 +02:00
c7fe987c5a core: fix missing serializer on AuthenticatedSession (#15323)
fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-30 21:30:34 +02:00
e48739c8a0 stages/email: remove superflous <td> from account_confirmation template (#15297)
🐛 FIX: stages/email: remove superflous <td> from account_confirmation template

Signed-off-by: Jonas Sulzer <jonas@violoncello.ch>
2025-06-30 11:02:52 +00:00
b2ee585c43 website: bump @types/node from 24.0.4 to 24.0.7 in /website (#15307)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.0.4 to 24.0.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.0.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 12:37:30 +02:00
97e8ea8e76 website: bump prettier-plugin-packagejson from 2.5.16 to 2.5.17 in /website (#15308)
website: bump prettier-plugin-packagejson in /website

Bumps [prettier-plugin-packagejson](https://github.com/matzkoh/prettier-plugin-packagejson) from 2.5.16 to 2.5.17.
- [Release notes](https://github.com/matzkoh/prettier-plugin-packagejson/releases)
- [Commits](https://github.com/matzkoh/prettier-plugin-packagejson/compare/v2.5.16...v2.5.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 12:37:11 +02:00
1f1e0c9db1 website: bump the eslint group in /website with 2 updates (#15309)
Bumps the eslint group in /website with 2 updates: [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) and [eslint](https://github.com/eslint/eslint).


Updates `@eslint/js` from 9.29.0 to 9.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/commits/v9.30.0/packages/js)

Updates `eslint` from 9.29.0 to 9.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/v9.29.0...v9.30.0)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.30.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 9.30.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 12:37:01 +02:00
ca47a803fe core: bump uvicorn[standard] from 0.34.3 to 0.35.0 (#15312)
Bumps [uvicorn[standard]](https://github.com/encode/uvicorn) from 0.34.3 to 0.35.0.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/docs/release-notes.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.34.3...0.35.0)

---
updated-dependencies:
- dependency-name: uvicorn[standard]
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 12:36:45 +02:00
c606eb53b0 core: bump goauthentik.io/api/v3 from 3.2025062.6 to 3.2025063.1 (#15306)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 09:32:40 +00:00
c2dc38e804 Merge branch 'main' into celery-2-dramatiq 2025-06-30 11:13:20 +02:00
9aad7e29a4 temporarly disable tenants/test_settings
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 11:11:52 +02:00
62357133b0 core: bump astral-sh/uv from 0.7.15 to 0.7.17 (#15311)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 10:03:54 +02:00
99d2d91257 core: bump sentry-sdk from 2.31.0 to 2.32.0 (#15314)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 10:02:43 +02:00
69d9363fce core: bump axllent/mailpit from v1.26.2 to v1.27.0 in /tests/e2e (#15315)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 10:02:28 +02:00
315f9073cc lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 09:43:15 +02:00
c94fa13826 move metricsmiddleware to package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 09:38:40 +02:00
6b3fbb0abf re-add workers count metric
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 06:38:31 +02:00
06191d6cfc re-add workers count metric
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 06:36:27 +02:00
c608dc5110 maybe fix tenant tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 05:38:24 +02:00
bb05d6063d saner values for tenacity
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 04:30:24 +02:00
c5b4a630c9 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 04:14:06 +02:00
4a73c65710 correct package deps
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 04:12:12 +02:00
51e645c26a Revert "fix most tenant tests"
This reverts commit d61995d0e2.
2025-06-30 04:09:53 +02:00
de3607b9a6 fix outposts e2e tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 04:07:42 +02:00
fb5804b914 fix outposts e2e tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 04:06:15 +02:00
287f41fed8 try fixing ldap e2e tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 03:56:42 +02:00
172b595a9f lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 03:54:41 +02:00
d61995d0e2 fix most tenant tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-30 03:47:30 +02:00
cfc7f6b993 core, web: update translations (#15298)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-30 03:17:37 +02:00
056460dac0 Merge branch 'main' into celery-2-dramatiq 2025-06-30 03:17:13 +02:00
bebbbe9b90 website/integrations: add omada controller doc (#14523)
* Adds omada controller doc and updated integration sidebar

* Update verification section

* WIP

* WIP

* Updated encoding section

* Finished document

* Applied suggestions

* Applied suggestions

* Entity ID changed to issuer

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omada-controller/index.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* And then

* Remove errant :::

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-06-28 15:50:22 +00:00
188d3c69c1 Change issuer from zulip to authentik in zulip integration documentation (#15296)
I tried to follow this documentation. My zulip instance (running docker-zulip 10.3-0)  did not recognize the IdP when a user returned from authentik to zulip, until I changed the issuer in the authentik settings from `zulip.company` to `authentik.company`.

Signed-off-by: CSDUMMI <31551856+CSDUMMI@users.noreply.github.com>
2025-06-28 13:25:54 +01:00
877f312145 website/integrations: bookstack: fix redirect URI (#15295)
Signed-off-by: Dominic R <dominic@sdko.org>
2025-06-28 11:13:19 +01:00
f471a98bc7 website/integrations: fix typo in actual budget (#15293)
docs: Update index.mdx

Signed-off-by: Bryan J. <132493975+chkpwd@users.noreply.github.com>
2025-06-27 12:52:42 -05:00
b30b736a71 fix scim tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 18:36:55 +02:00
d3aa43ced0 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 18:33:53 +02:00
92c837f7b5 fix more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 18:28:13 +02:00
7fcd65e318 fix outgoing sync tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 17:07:36 +02:00
e874cfc21d website: bump prettier from 3.6.1 to 3.6.2 in /website (#15280)
Bumps [prettier](https://github.com/prettier/prettier) from 3.6.1 to 3.6.2.
- [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/3.6.1...3.6.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-27 17:04:52 +02:00
ec7bdf74aa core, web: update translations (#15278)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-27 14:56:51 +00:00
9c01c7d890 fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 16:31:04 +02:00
bdb0564d4c fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 16:23:54 +02:00
e87bc94b95 release: backport 2025.6.3 (#15292)
release: 2025.6.3
2025-06-27 16:21:18 +02:00
09688f7a55 fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 15:49:03 +02:00
31bb995490 fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 15:46:34 +02:00
5d813438f0 fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 15:44:32 +02:00
a3865abaa9 website: changelog for security releases (#15291)
* website: changelog for security releases

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-27 15:42:02 +02:00
7100d3c674 security: fix CVE-2025-52553 (#15289)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-27 15:26:39 +02:00
d92764789f Merge branch 'main' into celery-2-dramatiq
LOGGER.error("message options", options=message.options)
2025-06-27 15:26:16 +02:00
c702fa1f95 fix some more tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 15:25:49 +02:00
786bada7d0 fix some tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-27 15:24:31 +02:00
c0c2d2ad3c website/docs: updated security release procedure (#15288)
* ci: skip translate compile

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ci: allow skipping build container for website

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update docs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix gha perms?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-27 14:18:29 +02:00
dc287989db translate: Updates for file web/xliff/en.xlf in zh-Hans (#15285)
Translate web/xliff/en.xlf in zh-Hans

100% translated source file: 'web/xliff/en.xlf'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 14:02:01 +02:00
03204f6943 translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#15284)
Translate django.po in zh-Hans

100% translated source file: 'django.po'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 14:01:48 +02:00
fcd369e466 translate: Updates for file web/xliff/en.xlf in zh_CN (#15283)
Translate web/xliff/en.xlf in zh_CN

100% translated source file: 'web/xliff/en.xlf'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 14:01:38 +02:00
cb79407bc1 translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#15282)
Translate locale/en/LC_MESSAGES/django.po in zh_CN

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 14:01:16 +02:00
04a88daf34 translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#15273)
Translate locale/en/LC_MESSAGES/django.po in it

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 13:59:54 +02:00
c6a49da5c3 translate: Updates for file web/xliff/en.xlf in it (#15272)
Translate web/xliff/en.xlf in it

100% translated source file: 'web/xliff/en.xlf'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-27 13:59:35 +02:00
bfeeecf3fa ci: more adjustable mirror options (#15287)
* custom mirror which doesn't get rid of other branches

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add workflow for manual semi-release

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make ci work on internal

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-27 13:48:20 +02:00
d86b5e7c8a web/packages: NPM workspace: Mini Cleanup (#14767)
* web: Move non-workspace package.

* web: Update ESBuild package version.

* web: Use NPM link to alias local package.

* web: Update lock.

* web: Fix regression where bundler is expected.
2025-06-26 17:29:35 -04:00
690766d377 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 18:52:44 +02:00
4990abdf4a ignore setup.py for test collection
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 18:52:18 +02:00
76616cf1c5 oupsi
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 18:42:22 +02:00
48c0b5449e tests run locally
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 18:34:28 +02:00
8956606564 fix metrics
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 18:05:01 +02:00
a95776891e website/docs: add hint that flows need cookies (#15252)
* website/docs: add hint that flows need cookies

The executor itself does not set a session cookie, but requires
one to be set before. This took me days to figure out, so maybe
this will be helpful to somebody in the future.

Signed-off-by: Leonardo Mörlein <git@irrelefant.net>

* Update website/docs/developer-docs/api/flow-executor.md

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Leonardo Mörlein <git@irrelefant.net>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-06-26 15:40:40 +00:00
0908d0b559 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 17:07:06 +02:00
7e5c90fcdc more make web
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 17:05:33 +02:00
4e210b8299 make web
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 17:01:15 +02:00
bf65ca4c70 move system tasks page to admin overview
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 16:58:31 +02:00
670a88659e readd syncstatuschart
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 16:57:30 +02:00
0ebbaeea6f add missing for ldap kerberos, add last status for schedules
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 16:45:26 +02:00
49a9911271 web: re-add sync status cards
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 16:31:23 +02:00
f3c0ca1a59 fix api
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 15:54:17 +02:00
64e7bff16c re-introduce sync status api
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 15:40:34 +02:00
f264989f9e simplify outpost signals
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 15:00:26 +02:00
031158fdba website: bump prettier from 3.6.0 to 3.6.1 in /website (#15263)
Bumps [prettier](https://github.com/prettier/prettier) from 3.6.0 to 3.6.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/3.6.0...3.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:51:40 +02:00
b2fbb92498 core: bump django-prometheus from 2.4.0 to 2.4.1 (#15253)
Bumps [django-prometheus](https://github.com/korfuri/django-prometheus) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/korfuri/django-prometheus/releases)
- [Changelog](https://github.com/django-commons/django-prometheus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/korfuri/django-prometheus/compare/v2.4.0...v2.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:51:29 +02:00
8f4353181e wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 14:38:08 +02:00
b1b6bf1a19 core, web: update translations (#15251)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-26 14:28:13 +02:00
179d9d0721 core: bump goauthentik.io/api/v3 from 3.2025062.5 to 3.2025062.6 (#15259)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025062.5 to 3.2025062.6.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025062.5...v3.2025062.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:25:27 +02:00
8e94d58851 core: bump google-api-python-client from 2.173.0 to 2.174.0 (#15255)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.173.0 to 2.174.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.173.0...v2.174.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  dependency-version: 2.174.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:25:10 +02:00
026669cfce core: bump msgraph-sdk from 1.34.0 to 1.35.0 (#15256)
Bumps [msgraph-sdk](https://github.com/microsoftgraph/msgraph-sdk-python) from 1.34.0 to 1.35.0.
- [Release notes](https://github.com/microsoftgraph/msgraph-sdk-python/releases)
- [Changelog](https://github.com/microsoftgraph/msgraph-sdk-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/microsoftgraph/msgraph-sdk-python/compare/v1.34.0...v1.35.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:25:01 +02:00
c83cea6963 core: bump astral-sh/uv from 0.7.14 to 0.7.15 (#15257)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.7.14 to 0.7.15.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.7.14...0.7.15)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.7.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:24:38 +02:00
8e01cc2df8 lifecycle/aws: bump aws-cdk from 2.1019.1 to 2.1019.2 in /lifecycle/aws (#15258)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1019.1 to 2.1019.2.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1019.2/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1019.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:23:22 +02:00
279cec203d core: bump django-guardian from 3.0.0 to 3.0.3 (#15254)
Bumps [django-guardian](https://github.com/django-guardian/django-guardian) from 3.0.0 to 3.0.3.
- [Release notes](https://github.com/django-guardian/django-guardian/releases)
- [Commits](https://github.com/django-guardian/django-guardian/compare/3.0.0...3.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:21:58 +02:00
41c5030c1e web: bump @sentry/browser from 9.31.0 to 9.32.0 in /web in the sentry group across 1 directory (#15260)
web: bump @sentry/browser in /web in the sentry group across 1 directory

Bumps the sentry group with 1 update in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 9.31.0 to 9.32.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/9.31.0...9.32.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:16:27 +02:00
3206fdb7ef website: bump the build group in /website with 6 updates (#15261)
Bumps the build group in /website with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.6` | `1.12.7` |


Updates `@swc/core-darwin-arm64` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

Updates `@swc/core-linux-arm64-gnu` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

Updates `@swc/core-linux-x64-gnu` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

Updates `@swc/html-darwin-arm64` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

Updates `@swc/html-linux-arm64-gnu` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

Updates `@swc/html-linux-x64-gnu` from 1.12.6 to 1.12.7
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.6...v1.12.7)

---
updated-dependencies:
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.12.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:16:18 +02:00
d7c0868eef website: bump @types/lodash from 4.17.18 to 4.17.19 in /website (#15262)
Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.18 to 4.17.19.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash)

---
updated-dependencies:
- dependency-name: "@types/lodash"
  dependency-version: 4.17.19
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:16:01 +02:00
7d96a89697 website: bump prettier-plugin-packagejson from 2.5.15 to 2.5.16 in /website (#15264)
website: bump prettier-plugin-packagejson in /website

Bumps [prettier-plugin-packagejson](https://github.com/matzkoh/prettier-plugin-packagejson) from 2.5.15 to 2.5.16.
- [Release notes](https://github.com/matzkoh/prettier-plugin-packagejson/releases)
- [Commits](https://github.com/matzkoh/prettier-plugin-packagejson/compare/v2.5.15...v2.5.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 14:15:45 +02:00
813b7aa8ba add helpful logs
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 13:52:11 +02:00
3bb3e0d1ef Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-26 13:46:51 +02:00
dfb0007777 translate: Updates for file web/xliff/en.xlf in it (#15266)
Translate web/xliff/en.xlf in it

100% translated source file: 'web/xliff/en.xlf'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-26 13:09:49 +02:00
816d9668eb website: add reference to "writing documentation" to readme (#15245)
* website: add reference to "writing documentation" to readme

As per: https://www.notion.so/authentiksecurity/Check-ins-17caee05b24e80a0aec6c7d508406435?source=copy_link#21daee05b24e8041adbadd3082ec7c8f

* Update website/README.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dominic R <dominic@sdko.org>

* lint readme

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-06-25 14:45:01 -05:00
371d35ec06 website: minimalistic readme (#14240)
* website: propose minimalistic readme

Introduce a minimalistic README for the website, link official website, and direct users to contribution guidelines, and finally also removes build commands from README (as source of truth is website)

Signed-off-by: Dominic R <dominic@sdko.org>

* Update README.md

Signed-off-by: Dominic R <dominic@sdko.org>

* fix md link 

Signed-off-by: Dominic R <dominic@sdko.org>

* I suppose i'm used to appending /CONTRUBUTING(.md or not) to contrib docs

Signed-off-by: Dominic R <dominic@sdko.org>

* add utm source as used on the main readme

Signed-off-by: Dominic R <dominic@sdko.org>

* Apply suggestions from code review

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/README.md

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
2025-06-25 18:00:14 +00:00
664d3593ca core: bump oauthlib from 3.2.2 to v3.3.1 (#15242) 2025-06-25 17:09:50 +00:00
7acd27eea8 core: bump boto3 from 1.38.29 to v1.38.43 (#15239) 2025-06-25 16:48:52 +00:00
83550dc50d core: bump multidict from 6.4.4 to v6.5.1 (#15241) 2025-06-25 16:48:37 +00:00
c272dd70fd core: bump click-plugins from 1.1.1 to v1.1.1.2 (#15240) 2025-06-25 16:48:24 +00:00
ae1d82dc69 core: bump python-dotenv from 1.1.0 to v1.1.1 (#15244) 2025-06-25 16:48:17 +00:00
dd42eeab62 core: bump pygments from 2.19.1 to v2.19.2 (#15243) 2025-06-25 16:48:01 +00:00
680db9bae6 events: use pending_user as user when possible (#15238)
* unrelated: dont show nested for user

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated: fix error when no extents in. map

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* events: use pending_user when possible

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix for identification stage "fake" user

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* better username rendering

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-25 18:22:51 +02:00
31b72751bc blueprints: add JSON tag to parse JSON from string (#15235) 2025-06-25 18:19:28 +02:00
101e5adeba WIP metrics
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 18:15:39 +02:00
8210067479 website/integrations: add ssh active user filter to sssd integration doc (#15203)
* Update sssd integration doc

* Improve language

* Update website/integrations/services/sssd/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/sssd/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/sssd/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/sssd/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/sssd/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Minor changes

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-06-25 17:01:23 +01:00
ae228c91e3 reset migrations
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 16:50:55 +02:00
411c52491e add worker api
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 16:50:21 +02:00
85869806a2 add logging middleware
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 15:53:18 +02:00
423911d974 web: bump API Client version (#15237)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-25 13:24:56 +00:00
d4ca070d76 core: better API validation for JSON fields (#15236)
* core: better API validation for JSON fields

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix web

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-25 15:05:32 +02:00
d132db475e lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 14:54:56 +02:00
13b5aa604b outgoing sync dispatch tasks (no magic)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 14:54:31 +02:00
97a5acdff5 ssf meta task
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 14:12:05 +02:00
ea38f2d120 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-25 14:03:23 +02:00
db1e8b291f website: bump @types/node from 24.0.3 to 24.0.4 in /website (#15230)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.0.3 to 24.0.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.0.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 13:47:04 +02:00
44ff6fce23 core: bump github.com/redis/go-redis/v9 from 9.10.0 to 9.11.0 (#15231)
Bumps [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) from 9.10.0 to 9.11.0.
- [Release notes](https://github.com/redis/go-redis/releases)
- [Changelog](https://github.com/redis/go-redis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/redis/go-redis/compare/v9.10.0...v9.11.0)

---
updated-dependencies:
- dependency-name: github.com/redis/go-redis/v9
  dependency-version: 9.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 13:47:01 +02:00
085c22a41a core: bump goauthentik.io/api/v3 from 3.2025062.4 to 3.2025062.5 (#15232)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025062.4 to 3.2025062.5.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025062.4...v3.2025062.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 13:46:58 +02:00
fb2887fa4b core: bump sentry-sdk from 2.30.0 to 2.31.0 (#15233)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.30.0 to 2.31.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/2.30.0...2.31.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 13:46:56 +02:00
ed41eb66de core, web: update translations (#15229)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-25 13:04:31 +02:00
ee8122baa7 website/docs: fix documentation for external group write commands in hashicorp-vault integrations (#15234)
Fix external group write

Signed-off-by: Balázs Hasprai <balazs.hasprai@hbalazs.com>
2025-06-25 10:01:17 +00:00
f0d70eef6f website/docs: enterprise: fix link for customer portal (#15225)
* website/docs: enterprise: fix link for customer portal

* fix more

Signed-off-by: Dominic R <dominic@sdko.org>

* fix more

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/enterprise/manage-enterprise.mdx

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-06-24 18:14:19 -05:00
ff966d763b providers/oauth2: add conformance tools (#15228)
add conformance tools

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-25 00:43:15 +02:00
e00b68cafe web: bump API Client version (#15227)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-24 22:13:34 +00:00
bf4e8dbedc core: include more authenticator details when possible (#15224)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-24 23:52:06 +02:00
d09b7757b6 root: fix some cases of invalid data triggering exceptions (#14799)
* sentry: separate checker if exception should be ignored

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use should_ignore_exception in flow executor (fix ParseError)

fix system exceptions for unsupported media type, json decode error

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* improve API validation

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-24 22:42:59 +02:00
ca2f0439f6 website/docs: add links to Customer Portal (#15223)
* add direct link to Portal, remove screenshot

* fix link

* Update website/docs/enterprise/get-started.md

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

---------

Signed-off-by: Jens L. <jens@beryju.org>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-06-24 15:34:37 -05:00
27b7b0b0e7 web/elements/empty-state: Fix issues with EmptyState and Loading Overlay (#15152)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web/element: empty-state should not have a default label when used as a loading indicator

* .

* web/bug/empty-state: Fix issues with EmptyState and Loading Overlay

- Add a method, `hasSlotted()`, to the Base component.
- Revise `EmptyState` to use `hasSlotted()`.
- Revise `LoadingOverlay` to use `hasSlotted()`.
- Provide (hopefully complete) Storybook stories for both
- Revise use of these components throughout the codebase.

The essential problem here was mine: I misunderstood what the Patternfly `SlotController` does (and,
yikes, how it does it). Slots aren't magical; they're just named containers, in which lightDOM
elements that appear between the opening and closing tags of a web component can be strategically
placed, shown or hidden, and to some extent styled, within the rendered and visible results of the
shadowDOM component that will fill the browser's RECT allocated to that component.

SlotController tries to associate the template with slots by creating the shadowDOM *first*, then
working backwards to see if there are lightDOM components to put into those slots.  That's not what
we want; we want to see if there are lightDOM components that meet our slot requirements and, if
there are, create corresponding slots for them.

That's what `hasSlotted()` does: it returns true or false to the question, "Is there currently in
the lightDOM for this component an entry requesting a known slot name?"  Components are free to do
what they want with that knowledge.

`<ak-empty-state>` now has several modes, all well-documented in the Storybook story.  But in short,
the Title is now a default slot; any HTML Element not sent to one of the named slots are put into
the Title.  The two named slots are `body` and `primary`.  The header is bold and large; body is
just text, and primary is boxed to indicate that one or more buttons should be placed there, to
allow interaction.

The extra modes are controlled by boolean attributes:

- `loading`: Shows the loading spinner, overriding the `icon` attribute
- `default`: Shows the loading spinner *and* the word "Loading" (i18n-aware).

The priority for all of these is:

- Has something in the default (header) slot: That text will be shown. Overrides both
- `default` overrides `loading`
- `loading`

q`<ak-loading-overlay>` is a specialized variant of `<ak-empty-state>` over what will become
`<ak-backdrop>`, but for now is just internal.  It allows only for the heading and primary slots,
forwarding them `<ak-empty-state>`.  Since this is literally the *Loading*Overlay, showing the
`loading` spinner is the default; to prevent it, pass `no-spinner` as an attribute.

* Grammatical error.

* Prettier had opinions that shouldn't have been aired in public.

* Prettier had opinions that shouldn't have been aired in public.

* Collapsing unnecessary boolean nest.

* fix typo

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* always render icon

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* missing default in flow exec

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated: fix loading interface

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* rename default attr

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix jsdoc

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-06-24 21:33:07 +02:00
94867aaebf task retries from admin ui
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 20:24:38 +02:00
0e67c1d818 rework event trigger tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 20:04:29 +02:00
2a460201bb fix blueprints not applying correctly
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 19:47:20 +02:00
f99cb3e9fb use correct watch folder
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 18:32:08 +02:00
88073305eb *: remove redundant user_logged_out signals (#15221) 2025-06-24 18:29:05 +02:00
e4bd05f444 more rework
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 17:47:46 +02:00
80c4eb9bef do not remove systemtask model
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 17:37:07 +02:00
96b4d5aee4 outposts
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 17:34:15 +02:00
37657e47a3 web: bump the eslint group across 2 directories with 3 updates (#15215)
Bumps the eslint group with 1 update in the /packages/eslint-config directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).
Bumps the eslint group with 1 update in the /web directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.34.1 to 8.35.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.35.0/packages/typescript-eslint)

Updates `@typescript-eslint/eslint-plugin` from 8.34.1 to 8.35.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/v8.35.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.1 to 8.35.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/v8.35.0/packages/parser)

Updates `typescript-eslint` from 8.34.1 to 8.35.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.35.0/packages/typescript-eslint)

Updates `@typescript-eslint/eslint-plugin` from 8.34.1 to 8.35.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/v8.35.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.1 to 8.35.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/v8.35.0/packages/parser)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.35.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.35.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:51:10 +02:00
0d649a70c9 core: bump github.com/getsentry/sentry-go from 0.33.0 to 0.34.0 (#15213)
Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.33.0 to 0.34.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.33.0...v0.34.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:51:00 +02:00
7ec3055018 web: bump @sentry/browser from 9.30.0 to 9.31.0 in /web in the sentry group across 1 directory (#15214)
web: bump @sentry/browser in /web in the sentry group across 1 directory

Bumps the sentry group with 1 update in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 9.30.0 to 9.31.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/9.30.0...9.31.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:50:48 +02:00
50ffce87c4 website: bump the eslint group in /website with 3 updates (#15216)
Bumps the eslint group in /website with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@typescript-eslint/eslint-plugin` from 8.34.1 to 8.35.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/v8.35.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.1 to 8.35.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/v8.35.0/packages/parser)

Updates `typescript-eslint` from 8.34.1 to 8.35.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.35.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:50:33 +02:00
a4393ac9f0 core: bump astral-sh/uv from 0.7.13 to 0.7.14 (#15217)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.7.13 to 0.7.14.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.7.13...0.7.14)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.7.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:50:14 +02:00
e235c854a5 website: bump the build group in /website with 6 updates (#15218)
Bumps the build group in /website with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.5` | `1.12.6` |


Updates `@swc/core-darwin-arm64` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

Updates `@swc/core-linux-arm64-gnu` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

Updates `@swc/core-linux-x64-gnu` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

Updates `@swc/html-darwin-arm64` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

Updates `@swc/html-linux-arm64-gnu` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

Updates `@swc/html-linux-x64-gnu` from 1.12.5 to 1.12.6
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.5...v1.12.6)

---
updated-dependencies:
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 16:50:04 +02:00
910b69f89d translate: Updates for file web/xliff/en.xlf in it (#15219)
Translate web/xliff/en.xlf in it

100% translated source file: 'web/xliff/en.xlf'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-24 16:49:41 +02:00
f89cc98014 sources/scim: add group patch support (#15212)
* set auth_via

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* allow requests with json content type

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix group schema

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start improving error handling

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add scim group patch for members

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated #1: fix debug check on startup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated fix #2: fix path for user page

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add group view tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add more user tests too

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-24 16:48:48 +02:00
6321537c8d actually reintroduce tasksmodel
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 16:10:16 +02:00
43975ec231 separate current and previous execution logs
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 16:01:40 +02:00
9b13922fc2 remove syncstatus leftovers
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 15:44:12 +02:00
031456629b add more tasks in ui
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 15:38:30 +02:00
2433ed1c9b blueprints fixup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 15:10:33 +02:00
9868d54320 show tasks/schedules for ldap source
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 15:00:30 +02:00
747a3ed6e9 show tasks/schedules for notif transports
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 14:35:56 +02:00
527e849ce2 show tasks/schedules for blueprints and ssf provider
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 14:29:55 +02:00
cfcd54ca19 sources: sync: use send_on_save
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 14:01:52 +02:00
faed9cd66e remove description from schedulespec
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 13:45:58 +02:00
897d0dbcbd show tasks/schedules for outpost service connections
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-24 13:43:31 +02:00
91a675a5a1 web/admin: point create application to wizard (#15211)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-24 01:36:20 +02:00
71be3acd1a web/elements: typing error when variables are not converted to string (#15169)
fix: typing error when variables are not converted to string

Co-authored-by: leandro.saraiva <leandro.saraiva@adonite.com>
2025-06-23 23:40:36 +02:00
0b6ab171ce website: bump prettier from 3.5.3 to 3.6.0 in /website (#15199)
* website: bump prettier from 3.5.3 to 3.6.0 in /website

Bumps [prettier](https://github.com/prettier/prettier) from 3.5.3 to 3.6.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/3.5.3...3.6.0)

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

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

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-06-23 21:29:14 +02:00
0c73572b0c ci: update daily tested versions (#15196)
* ci: update daily tested versions

Signed-off-by: Dominic R <dominic@sdko.org>

* Update ci-main-daily.yml

Co-authored-by: Jens L. <jens@beryju.org>
Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: Jens L. <jens@beryju.org>
2025-06-23 21:16:47 +02:00
03d0899a76 website/docs: sys mgmt: clean up certificates and add steps to download saml certs (#14497)
* website/docs: sys mgmt: clean up certificates and add steps to download
saml certs

* fix broken link

* Apply suggestions from code review

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Dominic R <dominic@sdko.org>

* Dewi review comments

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Dominic R <dominic@sdko.org>

* Apply suggestions from code review

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/docs/sys-mgmt/certificates.md

Signed-off-by: Dominic R <dominic@sdko.org>

* lint fix following header rm

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-06-23 18:56:50 +00:00
a12e991798 tasks results
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-23 17:27:58 +02:00
e5b86c3578 watch is now cmd line arg
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-23 17:18:23 +02:00
91f79c97d8 ci: fix CodeQL failing on cherry-pick PRs (#15205) 2025-06-23 16:55:08 +02:00
07ff433134 Merge branch 'main' into celery-2-dramatiq 2025-06-23 16:54:44 +02:00
21b3e0c8cb ensure descirptions'
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-23 16:54:13 +02:00
cbdec236dd run scheduler in broker
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-23 16:47:23 +02:00
2509ccde1c fix logs when task fails, make more options configurable
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-23 16:40:22 +02:00
19324c61a3 root: add system check for database encoding (#15186)
* root: add system check for database encoding

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* oops

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-23 15:17:48 +02:00
d297733614 enterprise/stages/source: update outer flow with context from inner flow (#15177)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-23 15:13:27 +02:00
f201f41a1b website: bump the build group in /website with 6 updates (#15200)
Bumps the build group in /website with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.4` | `1.12.5` |


Updates `@swc/core-darwin-arm64` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

Updates `@swc/core-linux-arm64-gnu` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

Updates `@swc/core-linux-x64-gnu` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

Updates `@swc/html-darwin-arm64` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

Updates `@swc/html-linux-arm64-gnu` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

Updates `@swc/html-linux-x64-gnu` from 1.12.4 to 1.12.5
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.4...v1.12.5)

---
updated-dependencies:
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 13:54:27 +02:00
f58f679171 web: bump the eslint group across 2 directories with 1 update (#15198)
Bumps the eslint group with 1 update in the /packages/eslint-config directory: [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import).
Bumps the eslint group with 1 update in the /web directory: [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import).


Updates `eslint-plugin-import` from 2.31.0 to 2.32.0
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.31.0...v2.32.0)

Updates `eslint-plugin-import` from 2.31.0 to 2.32.0
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.31.0...v2.32.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-version: 2.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint-plugin-import
  dependency-version: 2.32.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 13:54:16 +02:00
1bea5e38a1 core: bump goauthentik.io/api/v3 from 3.2025062.3 to 3.2025062.4 (#15197)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025062.3 to 3.2025062.4.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025062.3...v3.2025062.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 13:54:08 +02:00
4d1c63e7fa core: bump axllent/mailpit from v1.26.1 to v1.26.2 in /tests/e2e (#15201)
Bumps axllent/mailpit from v1.26.1 to v1.26.2.

---
updated-dependencies:
- dependency-name: axllent/mailpit
  dependency-version: v1.26.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 13:52:03 +02:00
e341032bf9 website/integrations: bitwarden: fix certificate download section (#15184)
* website/integrations: bitwarden: fix certificate download section

Fix whatever happened here

Signed-off-by: Dominic R <dominic@sdko.org>

* keep it as it was before I copy-pasted from stripe

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
2025-06-23 10:28:38 +01:00
e3ff242956 core, web: update translations (#15194)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-23 02:45:30 +02:00
c6756bf809 web: bump API Client version (#15193)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-23 02:45:03 +02:00
cf9b7eaa64 web/user: fix infinite loop when no user settings flow is set (#15188)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-23 01:49:43 +02:00
53d8f9bd8c stages/authenticator_webauthn: add option to configure max attempts (#15041)
* house keeping - migrate to session part 1

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup v2

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add max_attempts

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* teeny tiny cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add ui

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-23 01:49:07 +02:00
f76becfd86 stages/user_login: fix session binding logging (#15175)
* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix logging

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update test db?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ah there we go; fix mmdb not being reloaded with test settings

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-21 00:21:49 +02:00
080e2311fe website: bump the build group in /website with 6 updates (#15166)
Bumps the build group in /website with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.12.1` | `1.12.4` |


Updates `@swc/core-darwin-arm64` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

Updates `@swc/core-linux-arm64-gnu` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

Updates `@swc/core-linux-x64-gnu` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

Updates `@swc/html-darwin-arm64` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

Updates `@swc/html-linux-arm64-gnu` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

Updates `@swc/html-linux-x64-gnu` from 1.12.1 to 1.12.4
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.12.1...v1.12.4)

---
updated-dependencies:
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 22:14:03 +02:00
7e7b33dba7 run scheduler more often: TODO: move it back into the broker
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 19:30:46 +02:00
13e1e44626 cleanup scheduler
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 19:01:34 +02:00
e634f23fc8 fixup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 18:58:12 +02:00
8554a8e0c5 wip: description, fix total_seconds
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 18:45:02 +02:00
b80abffafc fix final todos in package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 18:13:15 +02:00
204f21699e emit event on exception
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 18:05:02 +02:00
0fd478fa3e better frontend task status
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 16:27:47 +02:00
eacc0eb546 website/docs: fix egregious maintenance fail (#15176)
fix egregious maintenance fail

Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-06-20 14:04:45 +00:00
7d7e47e972 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-20 15:32:58 +02:00
c77a54dc2a revert: web/flow: cleanup WebAuthn helper functions (#14460)" (#15172)
Revert "web/flow: cleanup WebAuthn helper functions (#14460)"

This reverts commit e86c40a00c.

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

# Conflicts:
#	web/package-lock.json
2025-06-20 15:01:51 +02:00
84781df51b root: update bumpversion changed list (#15170) 2025-06-20 14:50:42 +02:00
a640866534 lifecycle/aws: bump aws-cdk from 2.1018.1 to 2.1019.1 in /lifecycle/aws (#15162)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 14:30:46 +02:00
e070241407 core: bump google-api-python-client from 2.172.0 to 2.173.0 (#15167)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 14:30:38 +02:00
85985c3673 sources/ldap: fix sync on empty groups (#15158) 2025-06-20 13:34:12 +02:00
3abe6cd02c website/integrations: update actual budget docs link (#15156)
* Update index.mdx

Update URL to Actual Docs

Signed-off-by: theshoehorn <blair@blairschumann.com>

* Update website/integrations/services/actual-budget/index.mdx

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: theshoehorn <blair@blairschumann.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-06-20 08:51:31 +00:00
90c5b5c475 website: Docusaurus 3.8 shared fixes part 2 (#15155)
* website: Fix issue where files are ignored during build.

* Update packages/docusaurus-config/lib/routing.js

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>

* website: Update paths.

---------

Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-06-19 17:37:35 -04:00
adfbd1e0f2 events: fix map again and fix flaky tests (#15154)
* web/admin: fix OL Map loading external CSS

why are web developers like this dd8ccf12a1/elements/openlayers-core/ol-map.ts (L238)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix map chart display without map

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make test less flaky

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-19 23:10:17 +02:00
caa5617ce6 website: Touch up shared config. (#15153)
* website: Touch up shared config.

* website: Update deps. Fix issues surrounding cross-package formatting.
2025-06-19 14:11:55 -04:00
92a33a408f remove go worker stuff
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 19:10:38 +02:00
d18a54e9e6 scheduler now runs
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 19:08:50 +02:00
e6614a0705 move schedules to its package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 18:21:59 +02:00
4c491cf221 Merge branch 'main' into celery-2-dramatiq 2025-06-19 15:58:39 +02:00
d043dacece root: extract custom setup code (#15150) 2025-06-19 15:56:35 +02:00
17434c84cf Merge branch 'refactor-setup' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 15:51:53 +02:00
234fb2a0c6 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 15:51:06 +02:00
00612f921d root: extract custom setup code
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 15:36:21 +02:00
8b67015190 refactor setup.py
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 15:31:24 +02:00
5a5176e21f move middlewares to package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 14:57:17 +02:00
8980282a02 move command to package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-19 14:25:18 +02:00
6a367d4ddf web: bump @spotlightjs/spotlight from 3.0.0 to 3.0.1 in /web in the sentry group across 1 directory (#15144)
web: bump @spotlightjs/spotlight

Bumps the sentry group with 1 update in the /web directory: @spotlightjs/spotlight.


Updates `@spotlightjs/spotlight` from 3.0.0 to 3.0.1

---
updated-dependencies:
- dependency-name: "@spotlightjs/spotlight"
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 13:13:40 +02:00
e802c536a5 core, web: update translations (#15139)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-19 13:02:37 +02:00
39db9d9e6a core: bump msgraph-sdk from 1.33.0 to 1.34.0 (#15146)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 12:59:19 +02:00
f9ea4fc8e7 core: bump django-prometheus from 2.3.1 to 2.4.0 (#15147)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 12:59:02 +02:00
2320efc256 core: bump python-kadmin-rs from 0.6.0 to 0.6.1 (#15145)
Bumps [python-kadmin-rs](https://github.com/authentik-community/kadmin-rs) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/authentik-community/kadmin-rs/releases)
- [Commits](https://github.com/authentik-community/kadmin-rs/compare/kadmin/version/0.6.0...kadmin/version/0.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 12:56:36 +02:00
7b81cbbb43 core: bump goauthentik.io/api/v3 from 3.2025062.1 to 3.2025062.3 (#15148)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025062.1 to 3.2025062.3.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025062.1...v3.2025062.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 12:55:42 +02:00
2d480bffb4 events: disable all JSON autocomplete (#15138)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-19 02:36:55 +02:00
e6e0e49535 events: disable computation of autocomplete structure for event context (#15137)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-19 01:21:51 +02:00
31b90d5e1d web/admin: hide webhook URL by default (#15136)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-19 01:21:39 +02:00
e39f186e26 core: bump google-auth from 2.40.2 to v2.40.3 (#15122) 2025-06-19 00:23:19 +02:00
cdb1351cfb core: bump requests from 2.32.3 to v2.32.4 (#15129) 2025-06-18 23:36:53 +02:00
7b2c08073f core: bump zipp from 3.22.0 to v3.23.0 (#15134) 2025-06-18 23:16:08 +02:00
9ad4dfb522 core: bump yarl from 1.20.0 to v1.20.1 (#15133) 2025-06-18 23:15:13 +02:00
6b05195add core: bump watchfiles from 1.0.5 to v1.1.0 (#15132) 2025-06-18 23:14:49 +02:00
2ae095bfeb core: bump urllib3 from 2.4.0 to v2.5.0 (#15131) 2025-06-18 23:14:41 +02:00
cc68d8dd92 core: bump twisted from 24.11.0 to v25.5.0 (#15130) 2025-06-18 23:14:31 +02:00
89a158f66c core: bump propcache from 0.3.1 to v0.3.2 (#15128) 2025-06-18 23:14:23 +02:00
c56ee219a9 core: bump opentelemetry-api from 1.34.0 to v1.34.1 (#15127) 2025-06-18 23:14:15 +02:00
d596c08954 core: bump oauthlib from 3.2.2 to v3.3.0 (#15126) 2025-06-18 23:14:07 +02:00
070cdba521 core: bump multidict from 6.4.4 to v6.5.0 (#15125) 2025-06-18 23:13:58 +02:00
148d83c519 core: bump msgpack from 1.1.0 to v1.1.1 (#15124) 2025-06-18 23:13:50 +02:00
77146d2bac core: bump google-api-core from 2.25.0 to v2.25.1 (#15121) 2025-06-18 23:13:36 +02:00
03d5cde5fa core: bump kombu from 5.5.3 to v5.5.4 (#15123) 2025-06-18 23:13:13 +02:00
4af922165e core: bump frozenlist from 1.6.2 to v1.7.0 (#15120) 2025-06-18 23:13:00 +02:00
c3e57a7566 core: bump certifi from 2025.4.26 to v2025.6.15 (#15119) 2025-06-18 23:12:51 +02:00
423354fb09 core: bump boto3 from 1.38.29 to v1.38.38 (#15118) 2025-06-18 23:12:45 +02:00
f3fb064908 core: bump aiohttp from 3.12.8 to v3.12.13 (#15117) 2025-06-18 23:12:37 +02:00
492ef54d55 core: bump django-cte from 1.3.3 to 2.0.0 (#15088)
* core: bump django-cte from 1.3.3 to 2.0.0

Bumps [django-cte](https://github.com/dimagi/django-cte) from 1.3.3 to 2.0.0.
- [Changelog](https://github.com/dimagi/django-cte/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dimagi/django-cte/compare/v1.3.3...v2.0.0)

---
updated-dependencies:
- dependency-name: django-cte
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* update

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-06-18 17:46:29 +02:00
2ca9edb1bc fixup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 17:04:24 +02:00
61d970cda4 fixup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 17:02:48 +02:00
16fd9cab67 move all broker stuff to package, schedule is still todo
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 17:01:05 +02:00
8c7818a252 move more things to package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 16:12:12 +02:00
8eaed2b2f4 website: add netlify cache plugin (#15113)
* website: add cache plugin

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ok fine

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* absolute path?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix, include npm cache for docusaurus 3.8 and rspack

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-18 15:07:15 +02:00
092b6f7faf website: split integrations partially (#15076)
* config for split

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update alllll the links

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add redirect

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add separate job for integrations build

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Update website/netlify.toml

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Jens L. <jens@beryju.org>

* Revert "update alllll the links"

This reverts commit 872c5870a8.

* absolute relative URLs only

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* but use a plugin to rewrite them

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix external URL regex

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make rewrite plugin more re-usable

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix the reverse links

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* lint

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix root redirect

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix rediret

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix root redirect

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix redirect

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens L. <jens@beryju.org>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-06-18 14:51:26 +02:00
374779102a Merge branch 'main' into celery-2-dramatiq 2025-06-18 14:42:24 +02:00
d145f91be7 web: bump API Client version (#15112)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-18 13:50:12 +02:00
36c9929e1f events: add option to send notifications to event user (#15083)
* events: add option to send notifications to event user

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-18 13:39:56 +02:00
3fa6ce2e34 enterprise/web/admin: OSM for events (#9287)
* web: fix esbuild issue with style sheets

Getting ESBuild, Lit, and Storybook to all agree on how to read and parse stylesheets is a serious
pain. This fix better identifies the value types (instances) being passed from various sources in
the repo to the three *different* kinds of style processors we're using (the native one, the
polyfill one, and whatever the heck Storybook does internally).

Falling back to using older CSS instantiating techniques one era at a time seems to do the trick.
It's ugly, but in the face of the aggressive styling we use to avoid Flashes of Unstyled Content
(FLoUC), it's the logic with which we're left.

In standard mode, the following warning appears on the console when running a Flow:

```
Autofocus processing was blocked because a document already has a focused element.
```

In compatibility mode, the following **error** appears on the console when running a Flow:

```
crawler-inject.js:1106 Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
    at initDomMutationObservers (crawler-inject.js:1106:18)
    at crawler-inject.js:1114:24
    at Array.forEach (<anonymous>)
    at initDomMutationObservers (crawler-inject.js:1114:10)
    at crawler-inject.js:1549:1
initDomMutationObservers @ crawler-inject.js:1106
(anonymous) @ crawler-inject.js:1114
initDomMutationObservers @ crawler-inject.js:1114
(anonymous) @ crawler-inject.js:1549
```

Despite this error, nothing seems to be broken and flows work as anticipated.

* initial OSM for events

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove card title

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* split with volume

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add pin

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* basic map selection

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update pin

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* rewrite map points to be more imperative

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* zoom to fit

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Ken Sternberg <ken@goauthentik.io>
2025-06-18 13:36:40 +02:00
0ac854458a Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 13:28:02 +02:00
073c02cbb9 core: bump tornado from 6.4.2 to v6.5.1 (#15100) 2025-06-18 13:16:44 +02:00
bc8971f19d core: bump django-redis from 5.4.0 to 6.0.0 (#15107)
Bumps [django-redis](https://github.com/jazzband/django-redis) from 5.4.0 to 6.0.0.
- [Release notes](https://github.com/jazzband/django-redis/releases)
- [Changelog](https://github.com/jazzband/django-redis/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jazzband/django-redis/compare/5.4.0...6.0.0)

---
updated-dependencies:
- dependency-name: django-redis
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 10:49:10 +00:00
104c116678 web: bump API Client version (#15110)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-18 12:24:49 +02:00
f025d0d1d5 enterprise/search: ability to use more precise search queries (#7698)
* api: use DjangoQL for searches

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* expand search input and use textarea for multiline

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start implementing autocomplete

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* only use ql for events

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make QL search opt in

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make pretend json relation work

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix schema

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* test

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make autocomplete l1 work

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use forked js lib with types, separate QL

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* first attempt at making it fit our UI

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make dark theme somewhat work, fix search

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make more parts work

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make auto complete box be under cursor

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: ripplefcl <github@ripple.contact>

* remove django autocomplete for now

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* re-add event filtering

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix search when no ql is enabled

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make meta+enter submit, fix colour

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make dark theme

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* formatting

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* enterprise

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Update authentik/enterprise/search/apps.py

Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: Jens L. <jens@beryju.org>

* add json element autocomplete

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: ripplefcl <github@ripple.contact>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix query

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix search reset

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix dark theme

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens L. <jens@beryju.org>
Co-authored-by: ripplefcl <github@ripple.contact>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-18 12:23:00 +02:00
52115f9345 core, web: update translations (#15102)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-18 11:15:00 +02:00
b476551f13 web: bump @sentry/browser from 9.29.0 to 9.30.0 in /web in the sentry group across 1 directory (#15104)
web: bump @sentry/browser in /web in the sentry group across 1 directory

Bumps the sentry group with 1 update in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 9.29.0 to 9.30.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/9.29.0...9.30.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 11:14:24 +02:00
f9563c25cd core: bump github.com/jellydator/ttlcache/v3 from 3.3.0 to 3.4.0 (#15105)
Bumps [github.com/jellydator/ttlcache/v3](https://github.com/jellydator/ttlcache) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/jellydator/ttlcache/releases)
- [Commits](https://github.com/jellydator/ttlcache/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: github.com/jellydator/ttlcache/v3
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 11:14:15 +02:00
0067e6e155 website: bump @types/lodash from 4.17.17 to 4.17.18 in /website (#15106)
Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.17 to 4.17.18.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash)

---
updated-dependencies:
- dependency-name: "@types/lodash"
  dependency-version: 4.17.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 11:14:08 +02:00
ce183929d4 website/integrations: zipline: add offline_access scope (#15099)
Closes https://github.com/goauthentik/authentik/issues/15098

Signed-off-by: Dominic R <dominic@sdko.org>
2025-06-17 16:15:07 -05:00
2fdf345271 website/docs: Add steps to troubleshoot /initial-setup/ (#15011)
* Add steps to troubleshoot /initial-setup/

* fix linting

* Apply suggestions from code review

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* Apply suggestions from code review

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* add email part

* Apply suggestions from code review

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* Apply suggestions from code review

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* change wording

---------

Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-06-17 08:40:14 -05:00
bbcf8418b4 core, web: update translations (#15084)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-17 13:50:05 +02:00
dc57be46f4 website: bump the eslint group in /website with 3 updates (#15085)
Bumps the eslint group in /website with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@typescript-eslint/eslint-plugin` from 8.34.0 to 8.34.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/v8.34.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.0 to 8.34.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/v8.34.1/packages/parser)

Updates `typescript-eslint` from 8.34.0 to 8.34.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.34.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:31:27 +02:00
d68b3ba516 website: bump @types/node from 24.0.1 to 24.0.3 in /website (#15086)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.0.1 to 24.0.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:31:20 +02:00
a9c46cfcbd website: bump postcss from 8.5.5 to 8.5.6 in /website (#15087)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.5 to 8.5.6.
- [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.5.5...8.5.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:31:12 +02:00
c50353ebf6 core: bump webauthn from 2.5.2 to 2.6.0 (#15089)
Bumps [webauthn](https://github.com/duo-labs/py_webauthn) from 2.5.2 to 2.6.0.
- [Release notes](https://github.com/duo-labs/py_webauthn/releases)
- [Changelog](https://github.com/duo-labs/py_webauthn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/duo-labs/py_webauthn/compare/v2.5.2...v2.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:30:57 +02:00
db6be9e1b6 core: bump goauthentik.io/api/v3 from 3.2025061.2 to 3.2025062.1 (#15090)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025061.2 to 3.2025062.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025061.2...v3.2025062.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:30:50 +02:00
a74892886d web: bump the eslint group across 2 directories with 3 updates (#15091)
Bumps the eslint group with 1 update in the /packages/eslint-config directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).
Bumps the eslint group with 1 update in the /web directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.34.0 to 8.34.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.34.1/packages/typescript-eslint)

Updates `@typescript-eslint/eslint-plugin` from 8.34.0 to 8.34.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/v8.34.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.0 to 8.34.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/v8.34.1/packages/parser)

Updates `typescript-eslint` from 8.34.0 to 8.34.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.34.1/packages/typescript-eslint)

Updates `@typescript-eslint/eslint-plugin` from 8.34.0 to 8.34.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/v8.34.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.0 to 8.34.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/v8.34.1/packages/parser)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.34.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.34.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.34.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 13:30:42 +02:00
74cd4c2236 translate: Updates for file web/xliff/en.xlf in zh_CN (#15074)
Translate web/xliff/en.xlf in zh_CN

100% translated source file: 'web/xliff/en.xlf'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-17 13:28:56 +02:00
ef3bd7e77b translate: Updates for file web/xliff/en.xlf in zh-Hans (#15075)
Translate web/xliff/en.xlf in zh-Hans

100% translated source file: 'web/xliff/en.xlf'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-17 13:28:42 +02:00
3f5ad2baa4 ci: fix post-release e2e builds failing (#15082)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-17 09:10:26 +02:00
24805f087b web: bump API Client version (#15079)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-17 01:51:07 +02:00
9464b422a3 web/common: fix uiConfig not merged correctly (#15080)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-17 01:36:39 +02:00
da6d4ede51 root: backport version bump 2025.6.2 (#15078)
release: 2025.6.2
2025-06-17 00:21:39 +02:00
cecad5bfd3 website/integrations: add note to nextcloud OIDC config (#15073)
Add note to OIDC config
2025-06-16 16:47:16 +00:00
bc4b07d57b web/admin: remove all special cases of slug handling, replace with a "smart slug" component (#14983)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web/components: Remove all special cases of slug handling, replace with a "smart slug" component

This commit removes all special handling for the `slug` attribute in our text. A variant of the text
input control that can handle formatting-as-slugs has replaced all the slugificiation code; simply
drop it onto a page and tell it the (must be unique) selector from which to get the data to be
slugified. It only looks up one tier of the DOM so be careful that both the text input and its slug
accessory occupy the same DOM context.

## Details

### The Component

Now that we know a (lot) more about Lit, this component has been slightly updated to meet our
current standards.

- web/src/components/ak-slug-input.ts

Changes made:

- The "listen for the source object" has been moved to the `firstUpdated`, so that it no longer has
  to wait for the end of a render.
 - The `dirtyFlag` handler now uses the `@input` syntax.
- Updated the slug formatter to permit trailing dashes.
- Uses the `@bound` decorator, eliminating the need to do binding in the constructor (and so
  eliminating the constructor completely).

### Component uses:

The following components were revised to use `ak-slug-input` instead of a plain text input with the
slug-handling added by our forms manager.

- applications/ApplicationForm.ts
- flows/FlowForm.ts
- sources/kerberos/KerberosSourceForm.ts
- sources/ldap/LDAPSourceForm.ts
- sources/oauth/OAuthSourceForm.ts
- sources/plex/PlexSourceForm.ts
- sources/saml/SAMLSourceForm.ts
- sources/scim/SCIMSourceForm.ts

### Remove the redundant special slug handling code

- web/src/elements/forms/Form.ts
- web/src/elements/forms/HorizontalFormElement.ts

### A special case among special cases

- web/src/admin/stages/invitation/InvitationForm.ts

This form is our one case where we have a slug input field with no corresponding text source. Adding
a simple event handler to validate the value whenever it changed and write back a "clean" slug was
the most straightforward solution. I added a help line; it seemed "surprising" to ask someone for a
name and not follow the same rules as "names" everywhere else in our UI without explanation.

* After writing the commit message, I realized some of the comments I made MUST be added to the component.

* The `source` attribute needed its own comment to indicate that a `query()` compatible selector is expected.

* Added public/private/protected/# indicators to all fields.  Trying to balance between getting it 'right' and leaving an opening for harmonizing style-sharing and state-sharing between (text / textarea), slug, password and (visible / hidden / secret).

* Removed the ids as requested; the default "look for this" matches the original behavior without requiring it be hard-coded and unchangable.
2025-06-16 09:04:00 -07:00
e85d2d0096 Web/cleanup/empty state better slot handling (#14289)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web: remove Lit syntax from always true attributes

## What

Replaces instances of `?loading=${true}` and `?loading="${true}"` with `loading`

## Why

The Lit syntax is completely unnecessary when the attribute's state is constant, and it's a few
(just a few) extra CPU cycles for Lit to process that.

More to the point, it annoys me.

## How

```
$ perl -pi.bak -e 's/\?loading=\$\{true\}/loading/' $(rg -l '\?loading=\$\{true\}')
$ find . -name '*.bak' -exec rm {} \;
$ perl -pi.bak -e 's/\?loading="\$\{true\}"/loading/' $(rg -l '\?loading="\$\{true\}"')
$ find . -name '*.bak' -exec rm {} \;
```

* Prettier had opinions

* web: move optional textual information out of attributes and into slots

## What

Replaces instances of:

```
<ak-empty-state header=${msg(...)}></ak-empty-state>
```

with

```
<ak-empty-state><span slot="header">${msg(...)}</span></ak-empty-state>
```

## Why

1. It's correct.
2. It lets us elide the decorations for any slots we aren't using.
3. It's preparation for moving to Patternfly 5
4. It annoyed me.

## How

Since we already have Patternfly Elements installed, we have access to the PFE-Core, which has the
unbelievable useful `SlotsController`.  Using it, I created a conditional render template that will
only put in the header, body, and primary slots if there is something in the lightDOM requesting
those slots.  The conditional template will still put the spinner in if the header is not provided
but the loading state is true.

I then had to edit all the places where this is used. For about 30 of them, this script sufficed:

```
perl -pi.bak -e 's/header="?(\$\{msg\([^)]+\)\})"?>/><span slot="header">\1<\/span>/' \
     $(rg -l `<ak-empty-state[^>]header')

```

The other six had to be done by hand.  I have tested a handful of the automatic ones, and all of the
ones that were edited manually.  I'm pleasantly surprised that the textual rules [are inherited by
the slots as expected](https://htmlwithsuperpowers.netlify.app/styling/inheritable.htm).
2025-06-16 08:17:11 -07:00
be1dd3103b website/docs: release notes for 2025.6.2 (#15065)
* website/docs: release notes for `2025.6.2`

* fixup! website/docs: release notes for `2025.6.2`
2025-06-16 17:01:56 +02:00
5dfde5e1d3 website/docs: remove commented out config options (#15064)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-16 16:35:23 +02:00
1cfaddf49d start using things from the package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-16 16:19:21 +02:00
5ae69f5987 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-16 15:05:45 +02:00
7cb1e6d81e website/docs: postgres troubleshooting: get PGPASSWORD from POSTGRES_PASSWORD_FILE (#15039) 2025-06-16 15:00:23 +02:00
d7c3129b1c core: bump goauthentik/fips-python from 3.13.4-slim-bookworm-fips to 3.13.5-slim-bookworm-fips (#15058)
core: bump goauthentik/fips-python

Bumps goauthentik/fips-python from 3.13.4-slim-bookworm-fips to 3.13.5-slim-bookworm-fips.

---
updated-dependencies:
- dependency-name: goauthentik/fips-python
  dependency-version: 3.13.5-slim-bookworm-fips
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:28:39 +02:00
2a1d33021b website: bump the eslint group in /website with 2 updates (#15059)
Bumps the eslint group in /website with 2 updates: [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) and [eslint](https://github.com/eslint/eslint).


Updates `@eslint/js` from 9.28.0 to 9.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/commits/v9.29.0/packages/js)

Updates `eslint` from 9.28.0 to 9.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/v9.28.0...v9.29.0)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 9.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:28:21 +02:00
f273e49ae6 web: bump the wdio group across 1 directory with 3 updates (#14593)
Bumps the wdio group with 3 updates in the /web directory: [@wdio/browser-runner](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-browser-runner), [@wdio/cli](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-cli) and [@wdio/spec-reporter](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-spec-reporter).


Updates `@wdio/browser-runner` from 9.4.1 to 9.14.0
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v9.14.0/packages/wdio-browser-runner)

Updates `@wdio/cli` from 9.4.1 to 9.14.0
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v9.14.0/packages/wdio-cli)

Updates `@wdio/spec-reporter` from 9.1.2 to 9.14.0
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v9.14.0/packages/wdio-spec-reporter)

---
updated-dependencies:
- dependency-name: "@wdio/browser-runner"
  dependency-version: 9.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: wdio
- dependency-name: "@wdio/cli"
  dependency-version: 9.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: wdio
- dependency-name: "@wdio/spec-reporter"
  dependency-version: 9.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: wdio
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:28:10 +02:00
cc31957900 web: bump @sentry/browser from 9.28.1 to 9.29.0 in /web in the sentry group across 1 directory (#15061)
web: bump @sentry/browser in /web in the sentry group across 1 directory

Bumps the sentry group with 1 update in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 9.28.1 to 9.29.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/9.28.1...9.29.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:27:30 +02:00
b1ccdecc8e web: bump the eslint group across 2 directories with 2 updates (#15062)
Bumps the eslint group with 1 update in the /packages/eslint-config directory: [eslint](https://github.com/eslint/eslint).
Bumps the eslint group with 1 update in the /web directory: [eslint](https://github.com/eslint/eslint).


Updates `eslint` from 9.28.0 to 9.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/v9.28.0...v9.29.0)

Updates `@eslint/js` from 9.28.0 to 9.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/commits/v9.29.0/packages/js)

Updates `eslint` from 9.28.0 to 9.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/v9.28.0...v9.29.0)

Updates `@eslint/js` from 9.28.0 to 9.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/commits/v9.29.0/packages/js)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@eslint/js"
  dependency-version: 9.29.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 9.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@eslint/js"
  dependency-version: 9.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:27:17 +02:00
34031003a4 core: bump axllent/mailpit from v1.26.0 to v1.26.1 in /tests/e2e (#15060)
Bumps axllent/mailpit from v1.26.0 to v1.26.1.

---
updated-dependencies:
- dependency-name: axllent/mailpit
  dependency-version: v1.26.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:27:01 +02:00
055e1d1025 core: bump pydantic from 2.11.5 to 2.11.7 (#15063)
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.5 to 2.11.7.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.5...v2.11.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:26:52 +02:00
59a804273e providers/oauth2: bug fixes from conformance testing (#15056)
* check authorize request param earlier

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix basic suite?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* another actual fix; don't return access_token when using response_type id_token

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* only run basic+implicit for now, fix other tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

# Conflicts:
#	tests/openid_conformance/test_conformance.py

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-16 12:23:18 +02:00
bce70a1796 website/integrations: change nextcloud scope name to avoid confusion (#15050)
changed "profile" to "nextcloud"

Signed-off-by: Marlin <77961876+Keksmo@users.noreply.github.com>
2025-06-16 03:10:53 +02:00
e86c40a00c web/flow: cleanup WebAuthn helper functions (#14460)
* pass #1

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* pass #2

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add polyfill

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-16 02:39:50 +02:00
20e07486ee web/elements: fix typo in localeComparator (#15054)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-16 01:37:38 +02:00
0cb7cf2c96 stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#15049)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-15 23:54:50 +02:00
07736a90b2 translate: Updates for file locale/en/LC_MESSAGES/django.po in es (#15047)
* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

* Translate locale/en/LC_MESSAGES/django.po in es

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'es'.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-06-15 22:48:33 +02:00
ec28a86259 core, web: update translations (#15048)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-15 22:48:21 +02:00
260800c60b blueprints: add section support for organisation (#15045)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-15 20:49:21 +02:00
ee4780394d core, web: update translations (#15043)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-06-14 02:44:35 +02:00
23b746941f web/admin: adopt ak-hidden-text (#15042)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-06-14 02:22:14 +02:00
3c2ce40afd web/admin: Text and Textarea Fields that "hide" their contents until prompted (#15024)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web/admin: Provide `hidden` text and textarea components

## Details

This commit provides two new elements (technically, since they're API-unaware), one for `<input
type="text">`, and one for `<textarea>`, that provide for the ability to create fields that are (or
can be) hidden. A new boolean attribute, `revealed`, shows the state of the component (the content
is therefore *not* revealed by default).

It also includes a third new element, `ak-visibility-toggle`, that creates a hide/show toggle with
all the right icons, styling, and eventing.  It's straightforward, and isolating it improved the
DX of everything that uses that feature by quite a bit.

Storybook stories (with autodoc documentation) have been provided for `ak-hidden-text-input`,
`ak-hidden-textarea-input`, and `ak-visibility-toggle`.

## Maintenance Notice

As a maintenance detail, the field `ak-private-text` has been renamed `ak-secret-text` to reflect
its usage, and the places where it was used have all been changed to reflect that update.

* web/component: embed styling (for now) to handle the lightDom/shadowDom/slot conflicts in HorizontalLightComponent and HorizontalFormElement

* Comments and Types. I really shouldn't have to catch this stuff with my eyeballs.

* fix typo

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-06-14 01:48:34 +02:00
2aceed285e providers/rac: fixes prompt data not being merged with connection_settings (#15037)
* Fixes line that pulls in prompt data

* fallback to old settings

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-06-13 18:54:20 +02:00
c62e1d5457 backport broker changes
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-13 15:53:57 +02:00
5b8681b1af Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-13 15:42:17 +02:00
e0dcade9ad start moveing stuff to package. Check previous commit for changes to forwardport
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 18:37:50 +02:00
1a6ab7f24b broker improvements
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 18:37:31 +02:00
769844314c stop celery from being imported
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 16:02:07 +02:00
e211604860 implement send_on_startup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 16:00:56 +02:00
7ed711e8f0 pause schedules by default if needed
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 15:44:42 +02:00
196b276345 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 15:42:15 +02:00
3c62c80ff1 no hardcode in web
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 15:34:50 +02:00
a031f1107a wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 14:28:49 +02:00
8f399bba3f Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 14:22:40 +02:00
e354e877ea wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 14:18:33 +02:00
f254b8cf8c fully fix scim tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 13:00:17 +02:00
814b06322a fix todo
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 12:29:48 +02:00
217063ef7b fix db connection middleware
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 12:29:13 +02:00
c2f7883a5c start work on moving to a package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 12:12:31 +02:00
bd64c34787 init django-dramatiq-postgres package
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 10:36:21 +02:00
7518d4391f timelimit ms everywhere
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-12 10:15:55 +02:00
e67bd79c66 Merge branch 'main' into celery-2-dramatiq 2025-06-11 18:10:37 +02:00
2fc6da53c1 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 18:10:01 +02:00
250a98cf98 fix view_systemtask
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 18:03:37 +02:00
f2926fa1eb lint fix
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 17:45:05 +02:00
5e2af4a740 better finding of scheduled models
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 17:39:45 +02:00
41f2ca42cc remove duplicated inheritance model
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 17:32:25 +02:00
7ef547b357 restart front
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 17:25:23 +02:00
1a9c529e92 prevent further mis-registered actors from happening
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 14:40:21 +02:00
75d19bfe76 fix 'circular' import
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-11 14:28:04 +02:00
7f8f7376e0 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 16:55:56 +02:00
7c49de9cba wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 16:16:12 +02:00
00ac9b6367 reset migrations
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 15:46:44 +02:00
0e786f7040 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 15:42:40 +02:00
03d363ba84 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 15:38:52 +02:00
3f33519ec0 Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-10 14:49:45 +02:00
cae03beb6d wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-06 16:46:57 +02:00
e4c1e5aed0 revert web changes cause everything changes every 5 minutes ffs
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-06 16:42:03 +02:00
5acdd67cba wip: go embedded worker
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-06 16:16:29 +02:00
40dbac7a65 remove celery everywhere (almost)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-06 15:26:23 +02:00
1b4ed02959 Merge branch 'main' into celery-2-dramatiq 2025-06-06 14:55:50 +02:00
a95e730cdb wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 19:56:31 +02:00
d8c13159e1 reset migrations
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 18:42:11 +02:00
5f951ca3ef mmh
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 18:34:04 +02:00
338da72622 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 18:32:04 +02:00
90debcdd70 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 18:16:58 +02:00
3766ca86e8 uhhhhhhhhh
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 18:15:20 +02:00
59c8472628 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 17:03:23 +02:00
293616e6b0 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 17:00:48 +02:00
f7305d58b1 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 16:02:17 +02:00
ba94f63705 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 16:00:54 +02:00
06b2e0d14b Merge branch 'main' into celery-2-dramatiq 2025-06-05 15:59:53 +02:00
80a5f44491 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 15:56:29 +02:00
aca0bde46d remove bootstrap tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 15:47:12 +02:00
e671811ad2 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-05 15:05:26 +02:00
3140325493 Merge branch 'main' into celery-2-dramatiq 2025-06-04 18:54:58 +02:00
6c0b879b30 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 18:54:28 +02:00
0e0fb37dd7 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 18:34:44 +02:00
d2cacdc640 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 18:27:47 +02:00
e65fabf040 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 18:05:40 +02:00
107b96e65c wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 17:44:23 +02:00
5d7ba51872 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 17:05:36 +02:00
3037701a14 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 17:03:19 +02:00
66f8377c79 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 16:54:28 +02:00
86f81d92aa wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 16:53:20 +02:00
369437f2a1 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 16:51:59 +02:00
4b8b80f1d4 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 16:34:41 +02:00
f839aef33a wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 16:17:15 +02:00
eb87e30076 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-04 15:57:31 +02:00
4302f91028 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-03 18:25:49 +02:00
b0af20b0d5 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-03 15:35:23 +02:00
9b556cf4c4 Merge branch 'main' into celery-2-dramatiq 2025-06-03 15:34:31 +02:00
7118219544 Merge branch 'main' into celery-2-dramatiq 2025-05-26 18:29:26 +02:00
475600ea87 Merge branch 'main' into celery-2-dramatiq 2025-04-22 16:11:42 +02:00
2139e0be05 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-07 14:39:25 +02:00
a43a0f77fb improve ui
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-04 17:40:04 +02:00
8a073e8c60 Merge branch 'main' into celery-2-dramatiq 2025-04-04 17:22:01 +02:00
35640fcdfa wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-03 17:27:01 +02:00
c62f73400a schedule form and helpers
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-03 16:51:24 +02:00
c92cbd7e22 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-03 16:15:35 +02:00
c3b0d09e04 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-03 15:04:59 +02:00
c5a40fced3 Merge branch 'main' into celery-2-dramatiq 2025-04-03 15:03:50 +02:00
9cc6ebabc1 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-02 17:58:52 +02:00
e89659fe71 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-02 17:52:10 +02:00
3c1512028d lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-02 11:50:47 +02:00
c7f80686de start cleanup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-02 11:47:05 +02:00
8a8386cfcb wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-01 18:15:47 +02:00
e60165ee45 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-01 15:30:02 +02:00
bc6085adc7 leftovers
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-01 15:28:08 +02:00
d413e2875c fixu[
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-01 15:21:01 +02:00
144986f48e outgoing sync: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-01 15:20:37 +02:00
c9f1e34beb wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 20:29:46 +02:00
39f769b150 ldap source: finish migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 18:06:11 +02:00
78180e376f wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 17:26:33 +02:00
d51150102c fixup
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 15:14:02 +02:00
d5da16ad26 oauth source: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 15:13:28 +02:00
2b12e32fcf ssf: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 15:03:34 +02:00
a9b9661155 enterprise: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:37:49 +02:00
f5f0cef275 providers proxy: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:34:54 +02:00
b756965511 stages webauthn: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:32:17 +02:00
db900c4a42 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:25:58 +02:00
72cb62085b core: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:24:40 +02:00
5a42815850 source kerberos: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 14:17:32 +02:00
b9083a906a source plex: migrate tasks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-31 13:51:12 +02:00
04be734c49 email tasks migration
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-28 18:55:05 +01:00
1ed6cf7517 more migration
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-28 17:43:17 +01:00
d6c4f97158 fix outposts tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-28 17:40:01 +01:00
781704fa38 Merge branch 'main' into celery-2-dramatiq 2025-03-28 17:35:05 +01:00
28f4d7d566 fix tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-28 17:16:34 +01:00
991778b2be wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 20:00:32 +01:00
9465dafd7d wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 18:54:38 +01:00
75c13a8801 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 18:51:47 +01:00
8ae0f145f5 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 17:30:30 +01:00
4d0e0e3afe wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 15:44:54 +01:00
7aeb874ded wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 15:44:24 +01:00
ffc695f7b8 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 15:42:26 +01:00
93cb621af3 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:50:58 +01:00
3a34680196 run scheduler
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:46:36 +01:00
2335a3130a lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:35:16 +01:00
0bc4b69f52 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:33:56 +01:00
43c5c1276d wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:33:42 +01:00
a3ebfd9bbd wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-27 14:24:56 +01:00
af5b894e62 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-25 18:32:06 +01:00
c982066235 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-25 18:31:43 +01:00
1f6c1522b6 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-25 18:22:37 +01:00
bae83ba78e Merge branch 'main' into celery-2-dramatiq 2025-03-25 17:06:27 +01:00
0d0aeab4ee wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 21:01:34 +01:00
7fe91339ad wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 15:41:23 +01:00
44dea1d208 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 14:22:30 +01:00
6d3be40022 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 14:11:43 +01:00
07773f92a0 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 13:11:45 +01:00
dbc4a2b730 lint
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-24 12:51:20 +01:00
df15a78aac Merge branch 'main' into celery-2-dramatiq 2025-03-24 12:48:08 +01:00
61b517edfa Merge branch 'main' into celery-2-dramatiq
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-19 20:44:04 +01:00
082b342f65 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-14 12:42:46 +01:00
9a536ee4b9 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-12 18:07:55 +01:00
677f04cab2 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-11 17:25:51 +01:00
3ddc35cddc wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-11 17:13:07 +01:00
ae211226ef wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-10 17:20:15 +01:00
6662611347 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-09 13:38:15 +01:00
c4b988c632 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-09 02:30:38 +01:00
2b1ee8cd5c wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-09 01:49:03 +01:00
e8cfc2b91e wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-09 01:10:58 +01:00
de54404ab7 fix
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-08 23:43:10 +01:00
f8c3b64274 wip
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-03-08 23:20:12 +01:00
602 changed files with 19676 additions and 16885 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2025.6.1
current_version = 2025.6.3
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?
@ -21,6 +21,8 @@ optional_value = final
[bumpversion:file:package.json]
[bumpversion:file:package-lock.json]
[bumpversion:file:docker-compose.yml]
[bumpversion:file:schema.yml]
@ -31,6 +33,4 @@ optional_value = final
[bumpversion:file:internal/constants/constants.go]
[bumpversion:file:web/src/common/constants.ts]
[bumpversion:file:lifecycle/aws/template.yaml]

View File

@ -7,6 +7,9 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.toml]
indent_size = 2
[*.html]
indent_size = 2

View File

@ -38,6 +38,8 @@ jobs:
# Needed for attestation
id-token: write
attestations: write
# Needed for checkout
contents: read
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3.6.0

View File

@ -9,14 +9,15 @@ on:
jobs:
test-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
version:
- docs
- version-2025-4
- version-2025-2
- version-2024-12
steps:
- uses: actions/checkout@v4
- run: |

View File

@ -202,7 +202,7 @@ jobs:
uses: actions/cache@v4
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
- name: prepare web ui
if: steps.cache-web.outputs.cache-hit != 'true'
working-directory: web
@ -247,11 +247,13 @@ jobs:
# Needed for attestation
id-token: write
attestations: write
# Needed for checkout
contents: read
needs: ci-core-mark
uses: ./.github/workflows/_reusable-docker-build.yaml
secrets: inherit
with:
image_name: ghcr.io/goauthentik/dev-server
image_name: ${{ github.repository == 'goauthentik/authentik-internal' && 'ghcr.io/goauthentik/internal-server' || 'ghcr.io/goauthentik/dev-server' }}
release: false
pr-comment:
needs:

View File

@ -59,6 +59,7 @@ jobs:
with:
jobs: ${{ toJSON(needs) }}
build-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
timeout-minutes: 120
needs:
- ci-outpost-mark

View File

@ -41,7 +41,29 @@ jobs:
- name: test
working-directory: website/
run: npm test
build:
runs-on: ubuntu-latest
name: ${{ matrix.job }}
strategy:
fail-fast: false
matrix:
job:
- build
- build:integrations
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: website/package.json
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/
run: npm ci
- name: build
working-directory: website/
run: npm run ${{ matrix.job }}
build-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
permissions:
# Needed to upload container images to ghcr.io
@ -94,9 +116,11 @@ jobs:
needs:
- lint
- test
- build
- build-container
runs-on: ubuntu-latest
steps:
- uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: ${{ github.repository == 'goauthentik/authentik-internal' && 'build-container' || '[]' }}

View File

@ -2,7 +2,7 @@ name: "CodeQL"
on:
push:
branches: [main, "*", next, version*]
branches: [main, next, version*]
pull_request:
branches: [main]
schedule:

View File

@ -0,0 +1,21 @@
name: "authentik-repo-mirror-cleanup"
on:
workflow_dispatch:
jobs:
to_internal:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- if: ${{ env.MIRROR_KEY != '' }}
uses: BeryJu/repository-mirroring-action@5cf300935bc2e068f73ea69bcc411a8a997208eb
with:
target_repo_url: git@github.com:goauthentik/authentik-internal.git
ssh_private_key: ${{ secrets.GH_MIRROR_KEY }}
args: --tags --force --prune
env:
MIRROR_KEY: ${{ secrets.GH_MIRROR_KEY }}

View File

@ -11,11 +11,10 @@ jobs:
with:
fetch-depth: 0
- if: ${{ env.MIRROR_KEY != '' }}
uses: pixta-dev/repository-mirroring-action@v1
uses: BeryJu/repository-mirroring-action@5cf300935bc2e068f73ea69bcc411a8a997208eb
with:
target_repo_url:
git@github.com:goauthentik/authentik-internal.git
ssh_private_key:
${{ secrets.GH_MIRROR_KEY }}
target_repo_url: git@github.com:goauthentik/authentik-internal.git
ssh_private_key: ${{ secrets.GH_MIRROR_KEY }}
args: --tags --force
env:
MIRROR_KEY: ${{ secrets.GH_MIRROR_KEY }}

View File

@ -16,6 +16,7 @@ env:
jobs:
compile:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:
- id: generate_token

5
.gitignore vendored
View File

@ -100,9 +100,6 @@ ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
@ -166,8 +163,6 @@ dmypy.json
# pyenv
# celery beat schedule file
# SageMath parsed files
# Environments

View File

@ -6,13 +6,15 @@
"!Context scalar",
"!Enumerate sequence",
"!Env scalar",
"!Env sequence",
"!Find sequence",
"!Format sequence",
"!If sequence",
"!Index scalar",
"!KeyOf scalar",
"!Value scalar",
"!AtIndex scalar"
"!AtIndex scalar",
"!ParseJSON scalar"
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifierEnding": "index",

View File

@ -75,9 +75,9 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 4: Download uv
FROM ghcr.io/astral-sh/uv:0.7.13 AS uv
FROM ghcr.io/astral-sh/uv:0.7.17 AS uv
# Stage 5: Base python image
FROM ghcr.io/goauthentik/fips-python:3.13.4-slim-bookworm-fips AS python-base
FROM ghcr.io/goauthentik/fips-python:3.13.5-slim-bookworm-fips AS python-base
ENV VENV_PATH="/ak-root/.venv" \
PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \
@ -122,6 +122,7 @@ ENV UV_NO_BINARY_PACKAGE="cryptography lxml python-kadmin-rs xmlsec"
RUN --mount=type=bind,target=pyproject.toml,src=pyproject.toml \
--mount=type=bind,target=uv.lock,src=uv.lock \
--mount=type=bind,target=packages,src=packages \
--mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-dev
@ -167,6 +168,7 @@ COPY ./blueprints /blueprints
COPY ./lifecycle/ /lifecycle
COPY ./authentik/sources/kerberos/krb5.conf /etc/krb5.conf
COPY --from=go-builder /go/authentik /bin/authentik
COPY ./packages/ /ak-root/packages
COPY --from=python-deps /ak-root/.venv /ak-root/.venv
COPY --from=node-builder /work/web/dist/ /web/dist/
COPY --from=node-builder /work/web/authentik/ /web/authentik/

View File

@ -6,7 +6,7 @@ PWD = $(shell pwd)
UID = $(shell id -u)
GID = $(shell id -g)
NPM_VERSION = $(shell python -m scripts.generate_semver)
PY_SOURCES = authentik tests scripts lifecycle .github
PY_SOURCES = authentik packages tests scripts lifecycle .github
DOCKER_IMAGE ?= "authentik:test"
GEN_API_TS = gen-ts-api
@ -86,6 +86,10 @@ dev-create-db:
dev-reset: dev-drop-db dev-create-db migrate ## Drop and restore the Authentik PostgreSQL instance to a "fresh install" state.
update-test-mmdb: ## Update test GeoIP and ASN Databases
curl -L https://raw.githubusercontent.com/maxmind/MaxMind-DB/refs/heads/main/test-data/GeoLite2-ASN-Test.mmdb -o ${PWD}/tests/GeoLite2-ASN-Test.mmdb
curl -L https://raw.githubusercontent.com/maxmind/MaxMind-DB/refs/heads/main/test-data/GeoLite2-City-Test.mmdb -o ${PWD}/tests/GeoLite2-City-Test.mmdb
#########################
## API Schema
#########################
@ -94,7 +98,7 @@ gen-build: ## Extract the schema from the database
AUTHENTIK_DEBUG=true \
AUTHENTIK_TENANTS__ENABLED=true \
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
uv run ak make_blueprint_schema > blueprints/schema.json
uv run ak make_blueprint_schema --file blueprints/schema.json
AUTHENTIK_DEBUG=true \
AUTHENTIK_TENANTS__ENABLED=true \
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
@ -146,9 +150,9 @@ gen-client-ts: gen-clean-ts ## Build and install the authentik API for Typescri
--additional-properties=npmVersion=${NPM_VERSION} \
--git-repo-id authentik \
--git-user-id goauthentik
mkdir -p web/node_modules/@goauthentik/api
cd ${PWD}/${GEN_API_TS} && npm i
\cp -rf ${PWD}/${GEN_API_TS}/* web/node_modules/@goauthentik/api
cd ${PWD}/${GEN_API_TS} && npm link
cd ${PWD}/web && npm link @goauthentik/api
gen-client-py: gen-clean-py ## Build and install the authentik API for Python
docker run \

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2025.6.1"
__version__ = "2025.6.3"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -41,7 +41,7 @@ class VersionSerializer(PassiveSerializer):
return __version__
version_in_cache = cache.get(VERSION_CACHE_KEY)
if not version_in_cache: # pragma: no cover
update_latest_version.delay()
update_latest_version.send()
return __version__
return version_in_cache

View File

@ -1,57 +0,0 @@
"""authentik administration overview"""
from socket import gethostname
from django.conf import settings
from drf_spectacular.utils import extend_schema, inline_serializer
from packaging.version import parse
from rest_framework.fields import BooleanField, CharField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from authentik import get_full_version
from authentik.rbac.permissions import HasPermission
from authentik.root.celery import CELERY_APP
class WorkerView(APIView):
"""Get currently connected worker count."""
permission_classes = [HasPermission("authentik_rbac.view_system_info")]
@extend_schema(
responses=inline_serializer(
"Worker",
fields={
"worker_id": CharField(),
"version": CharField(),
"version_matching": BooleanField(),
},
many=True,
)
)
def get(self, request: Request) -> Response:
"""Get currently connected worker count."""
raw: list[dict[str, dict]] = CELERY_APP.control.ping(timeout=0.5)
our_version = parse(get_full_version())
response = []
for worker in raw:
key = list(worker.keys())[0]
version = worker[key].get("version")
version_matching = False
if version:
version_matching = parse(version) == our_version
response.append(
{"worker_id": key, "version": version, "version_matching": version_matching}
)
# In debug we run with `task_always_eager`, so tasks are ran on the main process
if settings.DEBUG: # pragma: no cover
response.append(
{
"worker_id": f"authentik-debug@{gethostname()}",
"version": get_full_version(),
"version_matching": True,
}
)
return Response(response)

View File

@ -3,6 +3,9 @@
from prometheus_client import Info
from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.config import CONFIG
from authentik.lib.utils.time import fqdn_rand
from authentik.tasks.schedules.lib import ScheduleSpec
PROM_INFO = Info("authentik_version", "Currently running authentik version")
@ -30,3 +33,15 @@ class AuthentikAdminConfig(ManagedAppConfig):
notification_version = notification.event.context["new_version"]
if LOCAL_VERSION >= parse(notification_version):
notification.delete()
@property
def global_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.admin.tasks import update_latest_version
return [
ScheduleSpec(
actor=update_latest_version,
crontab=f"{fqdn_rand('admin_latest_version')} * * * *",
paused=CONFIG.get_bool("disable_update_check"),
),
]

View File

@ -1,15 +0,0 @@
"""authentik admin settings"""
from celery.schedules import crontab
from django_tenants.utils import get_public_schema_name
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"admin_latest_version": {
"task": "authentik.admin.tasks.update_latest_version",
"schedule": crontab(minute=fqdn_rand("admin_latest_version"), hour="*"),
"tenant_schemas": [get_public_schema_name()],
"options": {"queue": "authentik_scheduled"},
}
}

View File

@ -1,35 +0,0 @@
"""admin signals"""
from django.dispatch import receiver
from packaging.version import parse
from prometheus_client import Gauge
from authentik import get_full_version
from authentik.root.celery import CELERY_APP
from authentik.root.monitoring import monitoring_set
GAUGE_WORKERS = Gauge(
"authentik_admin_workers",
"Currently connected workers, their versions and if they are the same version as authentik",
["version", "version_matched"],
)
_version = parse(get_full_version())
@receiver(monitoring_set)
def monitoring_set_workers(sender, **kwargs):
"""Set worker gauge"""
raw: list[dict[str, dict]] = CELERY_APP.control.ping(timeout=0.5)
worker_version_count = {}
for worker in raw:
key = list(worker.keys())[0]
version = worker[key].get("version")
version_matching = False
if version:
version_matching = parse(version) == _version
worker_version_count.setdefault(version, {"count": 0, "matching": version_matching})
worker_version_count[version]["count"] += 1
for version, stats in worker_version_count.items():
GAUGE_WORKERS.labels(version, stats["matching"]).set(stats["count"])

View File

@ -2,6 +2,8 @@
from django.core.cache import cache
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask
from dramatiq import actor
from packaging.version import parse
from requests import RequestException
from structlog.stdlib import get_logger
@ -9,10 +11,9 @@ from structlog.stdlib import get_logger
from authentik import __version__, get_build_hash
from authentik.admin.apps import PROM_INFO
from authentik.events.models import Event, EventAction
from authentik.events.system_tasks import SystemTask, TaskStatus, prefill_task
from authentik.lib.config import CONFIG
from authentik.lib.utils.http import get_http_session
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
LOGGER = get_logger()
VERSION_NULL = "0.0.0"
@ -32,13 +33,12 @@ def _set_prom_info():
)
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def update_latest_version(self: SystemTask):
"""Update latest version info"""
@actor(description=_("Update latest version info."))
def update_latest_version():
self: Task = CurrentTask.get_task()
if CONFIG.get_bool("disable_update_check"):
cache.set(VERSION_CACHE_KEY, VERSION_NULL, VERSION_CACHE_TIMEOUT)
self.set_status(TaskStatus.WARNING, "Version check disabled.")
self.info("Version check disabled.")
return
try:
response = get_http_session().get(
@ -48,7 +48,7 @@ def update_latest_version(self: SystemTask):
data = response.json()
upstream_version = data.get("stable", {}).get("version")
cache.set(VERSION_CACHE_KEY, upstream_version, VERSION_CACHE_TIMEOUT)
self.set_status(TaskStatus.SUCCESSFUL, "Successfully updated latest Version")
self.info("Successfully updated latest Version")
_set_prom_info()
# Check if upstream version is newer than what we're running,
# and if no event exists yet, create one.
@ -71,7 +71,7 @@ def update_latest_version(self: SystemTask):
).save()
except (RequestException, IndexError) as exc:
cache.set(VERSION_CACHE_KEY, VERSION_NULL, VERSION_CACHE_TIMEOUT)
self.set_error(exc)
raise exc
_set_prom_info()

View File

@ -29,13 +29,6 @@ class TestAdminAPI(TestCase):
body = loads(response.content)
self.assertEqual(body["version_current"], __version__)
def test_workers(self):
"""Test Workers API"""
response = self.client.get(reverse("authentik_api:admin_workers"))
self.assertEqual(response.status_code, 200)
body = loads(response.content)
self.assertEqual(len(body), 0)
def test_apps(self):
"""Test apps API"""
response = self.client.get(reverse("authentik_api:apps-list"))

View File

@ -30,7 +30,7 @@ class TestAdminTasks(TestCase):
"""Test Update checker with valid response"""
with Mocker() as mocker, CONFIG.patch("disable_update_check", False):
mocker.get("https://version.goauthentik.io/version.json", json=RESPONSE_VALID)
update_latest_version.delay().get()
update_latest_version.send()
self.assertEqual(cache.get(VERSION_CACHE_KEY), "99999999.9999999")
self.assertTrue(
Event.objects.filter(
@ -40,7 +40,7 @@ class TestAdminTasks(TestCase):
).exists()
)
# test that a consecutive check doesn't create a duplicate event
update_latest_version.delay().get()
update_latest_version.send()
self.assertEqual(
len(
Event.objects.filter(
@ -56,7 +56,7 @@ class TestAdminTasks(TestCase):
"""Test Update checker with invalid response"""
with Mocker() as mocker:
mocker.get("https://version.goauthentik.io/version.json", status_code=400)
update_latest_version.delay().get()
update_latest_version.send()
self.assertEqual(cache.get(VERSION_CACHE_KEY), "0.0.0")
self.assertFalse(
Event.objects.filter(
@ -67,14 +67,15 @@ class TestAdminTasks(TestCase):
def test_version_disabled(self):
"""Test Update checker while its disabled"""
with CONFIG.patch("disable_update_check", True):
update_latest_version.delay().get()
update_latest_version.send()
self.assertEqual(cache.get(VERSION_CACHE_KEY), "0.0.0")
def test_clear_update_notifications(self):
"""Test clear of previous notification"""
admin_config = apps.get_app_config("authentik_admin")
Event.objects.create(
action=EventAction.UPDATE_AVAILABLE, context={"new_version": "99999999.9999999.9999999"}
action=EventAction.UPDATE_AVAILABLE,
context={"new_version": "99999999.9999999.9999999"},
)
Event.objects.create(action=EventAction.UPDATE_AVAILABLE, context={"new_version": "1.1.1"})
Event.objects.create(action=EventAction.UPDATE_AVAILABLE, context={})

View File

@ -6,13 +6,11 @@ from authentik.admin.api.meta import AppsViewSet, ModelViewSet
from authentik.admin.api.system import SystemView
from authentik.admin.api.version import VersionView
from authentik.admin.api.version_history import VersionHistoryViewSet
from authentik.admin.api.workers import WorkerView
api_urlpatterns = [
("admin/apps", AppsViewSet, "apps"),
("admin/models", ModelViewSet, "models"),
path("admin/version/", VersionView.as_view(), name="admin_version"),
("admin/version/history", VersionHistoryViewSet, "version_history"),
path("admin/workers/", WorkerView.as_view(), name="admin_workers"),
path("admin/system/", SystemView.as_view(), name="admin_system"),
]

View File

@ -39,7 +39,7 @@ class BlueprintInstanceSerializer(ModelSerializer):
"""Ensure the path (if set) specified is retrievable"""
if path == "" or path.startswith(OCI_PREFIX):
return path
files: list[dict] = blueprints_find_dict.delay().get()
files: list[dict] = blueprints_find_dict.send().get_result(block=True)
if path not in [file["path"] for file in files]:
raise ValidationError(_("Blueprint file does not exist"))
return path
@ -115,7 +115,7 @@ class BlueprintInstanceViewSet(UsedByMixin, ModelViewSet):
@action(detail=False, pagination_class=None, filter_backends=[])
def available(self, request: Request) -> Response:
"""Get blueprints"""
files: list[dict] = blueprints_find_dict.delay().get()
files: list[dict] = blueprints_find_dict.send().get_result(block=True)
return Response(files)
@permission_required("authentik_blueprints.view_blueprintinstance")
@ -129,5 +129,5 @@ class BlueprintInstanceViewSet(UsedByMixin, ModelViewSet):
def apply(self, request: Request, *args, **kwargs) -> Response:
"""Apply a blueprint"""
blueprint = self.get_object()
apply_blueprint.delay(str(blueprint.pk)).get()
apply_blueprint.send_with_options(args=(blueprint.pk,), rel_obj=blueprint)
return self.retrieve(request, *args, **kwargs)

View File

@ -6,9 +6,12 @@ from inspect import ismethod
from django.apps import AppConfig
from django.db import DatabaseError, InternalError, ProgrammingError
from dramatiq.broker import get_broker
from structlog.stdlib import BoundLogger, get_logger
from authentik.lib.utils.time import fqdn_rand
from authentik.root.signals import startup
from authentik.tasks.schedules.lib import ScheduleSpec
class ManagedAppConfig(AppConfig):
@ -34,7 +37,7 @@ class ManagedAppConfig(AppConfig):
def import_related(self):
"""Automatically import related modules which rely on just being imported
to register themselves (mainly django signals and celery tasks)"""
to register themselves (mainly django signals and tasks)"""
def import_relative(rel_module: str):
try:
@ -80,6 +83,16 @@ class ManagedAppConfig(AppConfig):
func._authentik_managed_reconcile = ManagedAppConfig.RECONCILE_GLOBAL_CATEGORY
return func
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
"""Get a list of schedule specs that must exist in each tenant"""
return []
@property
def global_schedule_specs(self) -> list[ScheduleSpec]:
"""Get a list of schedule specs that must exist in the default tenant"""
return []
def _reconcile_tenant(self) -> None:
"""reconcile ourselves for tenanted methods"""
from authentik.tenants.models import Tenant
@ -100,8 +113,12 @@ class ManagedAppConfig(AppConfig):
"""
from django_tenants.utils import get_public_schema_name, schema_context
with schema_context(get_public_schema_name()):
self._reconcile(self.RECONCILE_GLOBAL_CATEGORY)
try:
with schema_context(get_public_schema_name()):
self._reconcile(self.RECONCILE_GLOBAL_CATEGORY)
except (DatabaseError, ProgrammingError, InternalError) as exc:
self.logger.debug("Failed to access database to run reconcile", exc=exc)
return
class AuthentikBlueprintsConfig(ManagedAppConfig):
@ -112,19 +129,29 @@ class AuthentikBlueprintsConfig(ManagedAppConfig):
verbose_name = "authentik Blueprints"
default = True
@ManagedAppConfig.reconcile_global
def load_blueprints_v1_tasks(self):
"""Load v1 tasks"""
self.import_module("authentik.blueprints.v1.tasks")
@ManagedAppConfig.reconcile_tenant
def blueprints_discovery(self):
"""Run blueprint discovery"""
from authentik.blueprints.v1.tasks import blueprints_discovery, clear_failed_blueprints
blueprints_discovery.delay()
clear_failed_blueprints.delay()
def import_models(self):
super().import_models()
self.import_module("authentik.blueprints.v1.meta.apply_blueprint")
@ManagedAppConfig.reconcile_global
def tasks_middlewares(self):
from authentik.blueprints.v1.tasks import BlueprintWatcherMiddleware
get_broker().add_middleware(BlueprintWatcherMiddleware())
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.blueprints.v1.tasks import blueprints_discovery, clear_failed_blueprints
return [
ScheduleSpec(
actor=blueprints_discovery,
crontab=f"{fqdn_rand('blueprints_v1_discover')} * * * *",
send_on_startup=True,
),
ScheduleSpec(
actor=clear_failed_blueprints,
crontab=f"{fqdn_rand('blueprints_v1_cleanup')} * * * *",
send_on_startup=True,
),
]

View File

@ -72,20 +72,33 @@ class Command(BaseCommand):
"additionalProperties": True,
},
"entries": {
"type": "array",
"items": {
"oneOf": [],
},
"anyOf": [
{
"type": "array",
"items": {"$ref": "#/$defs/blueprint_entry"},
},
{
"type": "object",
"additionalProperties": {
"type": "array",
"items": {"$ref": "#/$defs/blueprint_entry"},
},
},
],
},
},
"$defs": {},
"$defs": {"blueprint_entry": {"oneOf": []}},
}
def add_arguments(self, parser):
parser.add_argument("--file", type=str)
@no_translations
def handle(self, *args, **options):
def handle(self, *args, file: str, **options):
"""Generate JSON Schema for blueprints"""
self.build()
self.stdout.write(dumps(self.schema, indent=4, default=Command.json_default))
with open(file, "w") as _schema:
_schema.write(dumps(self.schema, indent=4, default=Command.json_default))
@staticmethod
def json_default(value: Any) -> Any:
@ -112,7 +125,7 @@ class Command(BaseCommand):
}
)
model_path = f"{model._meta.app_label}.{model._meta.model_name}"
self.schema["properties"]["entries"]["items"]["oneOf"].append(
self.schema["$defs"]["blueprint_entry"]["oneOf"].append(
self.template_entry(model_path, model, serializer)
)

View File

@ -3,6 +3,7 @@
from pathlib import Path
from uuid import uuid4
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.utils.translation import gettext_lazy as _
@ -71,6 +72,13 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel):
enabled = models.BooleanField(default=True)
managed_models = ArrayField(models.TextField(), default=list)
# Manual link to tasks instead of using TasksModel because of loop imports
tasks = GenericRelation(
"authentik_tasks.Task",
content_type_field="rel_obj_content_type",
object_id_field="rel_obj_id",
)
class Meta:
verbose_name = _("Blueprint Instance")
verbose_name_plural = _("Blueprint Instances")

View File

@ -1,18 +0,0 @@
"""blueprint Settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"blueprints_v1_discover": {
"task": "authentik.blueprints.v1.tasks.blueprints_discovery",
"schedule": crontab(minute=fqdn_rand("blueprints_v1_discover"), hour="*"),
"options": {"queue": "authentik_scheduled"},
},
"blueprints_v1_cleanup": {
"task": "authentik.blueprints.v1.tasks.clear_failed_blueprints",
"schedule": crontab(minute=fqdn_rand("blueprints_v1_cleanup"), hour="*"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -0,0 +1,2 @@
# Import all v1 tasks for auto task discovery
from authentik.blueprints.v1.tasks import * # noqa: F403

View File

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

View File

@ -37,6 +37,7 @@ entries:
- attrs:
attributes:
env_null: !Env [bar-baz, null]
json_parse: !ParseJSON '{"foo": "bar"}'
policy_pk1:
!Format [
"%s-%s",

View File

@ -35,6 +35,6 @@ def blueprint_tester(file_name: Path) -> Callable:
for blueprint_file in Path("blueprints/").glob("**/*.yaml"):
if "local" in str(blueprint_file):
if "local" in str(blueprint_file) or "testing" in str(blueprint_file):
continue
setattr(TestPackaged, f"test_blueprint_{blueprint_file}", blueprint_tester(blueprint_file))

View File

@ -5,7 +5,6 @@ from collections.abc import Callable
from django.apps import apps
from django.test import TestCase
from authentik.blueprints.v1.importer import is_model_allowed
from authentik.lib.models import SerializerModel
from authentik.providers.oauth2.models import RefreshToken
@ -22,10 +21,13 @@ def serializer_tester_factory(test_model: type[SerializerModel]) -> Callable:
return
model_class = test_model()
self.assertTrue(isinstance(model_class, SerializerModel))
# Models that have subclasses don't have to have a serializer
if len(test_model.__subclasses__()) > 0:
return
self.assertIsNotNone(model_class.serializer)
if model_class.serializer.Meta().model == RefreshToken:
return
self.assertEqual(model_class.serializer.Meta().model, test_model)
self.assertTrue(issubclass(test_model, model_class.serializer.Meta().model))
return tester
@ -34,6 +36,6 @@ for app in apps.get_app_configs():
if not app.label.startswith("authentik"):
continue
for model in app.get_models():
if not is_model_allowed(model):
if not issubclass(model, SerializerModel):
continue
setattr(TestModels, f"test_{app.label}_{model.__name__}", serializer_tester_factory(model))

View File

@ -215,6 +215,7 @@ class TestBlueprintsV1(TransactionTestCase):
},
"nested_context": "context-nested-value",
"env_null": None,
"json_parse": {"foo": "bar"},
"at_index_sequence": "foo",
"at_index_sequence_default": "non existent",
"at_index_mapping": 2,

View File

@ -54,7 +54,7 @@ class TestBlueprintsV1Tasks(TransactionTestCase):
file.seek(0)
file_hash = sha512(file.read().encode()).hexdigest()
file.flush()
blueprints_discovery()
blueprints_discovery.send()
instance = BlueprintInstance.objects.filter(name=blueprint_id).first()
self.assertEqual(instance.last_applied_hash, file_hash)
self.assertEqual(
@ -82,7 +82,7 @@ class TestBlueprintsV1Tasks(TransactionTestCase):
)
)
file.flush()
blueprints_discovery()
blueprints_discovery.send()
blueprint = BlueprintInstance.objects.filter(name="foo").first()
self.assertEqual(
blueprint.last_applied_hash,
@ -107,7 +107,7 @@ class TestBlueprintsV1Tasks(TransactionTestCase):
)
)
file.flush()
blueprints_discovery()
blueprints_discovery.send()
blueprint.refresh_from_db()
self.assertEqual(
blueprint.last_applied_hash,

View File

@ -6,6 +6,7 @@ from copy import copy
from dataclasses import asdict, dataclass, field, is_dataclass
from enum import Enum
from functools import reduce
from json import JSONDecodeError, loads
from operator import ixor
from os import getenv
from typing import Any, Literal, Union
@ -191,11 +192,18 @@ class Blueprint:
"""Dataclass used for a full export"""
version: int = field(default=1)
entries: list[BlueprintEntry] = field(default_factory=list)
entries: list[BlueprintEntry] | dict[str, list[BlueprintEntry]] = field(default_factory=list)
context: dict = field(default_factory=dict)
metadata: BlueprintMetadata | None = field(default=None)
def iter_entries(self) -> Iterable[BlueprintEntry]:
if isinstance(self.entries, dict):
for _section, entries in self.entries.items():
yield from entries
else:
yield from self.entries
class YAMLTag:
"""Base class for all YAML Tags"""
@ -226,7 +234,7 @@ class KeyOf(YAMLTag):
self.id_from = node.value
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
for _entry in blueprint.entries:
for _entry in blueprint.iter_entries():
if _entry.id == self.id_from and _entry._state.instance:
# Special handling for PolicyBindingModels, as they'll have a different PK
# which is used when creating policy bindings
@ -284,6 +292,22 @@ class Context(YAMLTag):
return value
class ParseJSON(YAMLTag):
"""Parse JSON from context/env/etc value"""
raw: str
def __init__(self, loader: "BlueprintLoader", node: ScalarNode) -> None:
super().__init__()
self.raw = node.value
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
try:
return loads(self.raw)
except JSONDecodeError as exc:
raise EntryInvalidError.from_entry(exc, entry) from exc
class Format(YAMLTag):
"""Format a string"""
@ -659,6 +683,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!Value", Value)
self.add_constructor("!Index", Index)
self.add_constructor("!AtIndex", AtIndex)
self.add_constructor("!ParseJSON", ParseJSON)
class EntryInvalidError(SentryIgnoredException):

View File

@ -57,7 +57,6 @@ from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
EndpointDeviceConnection,
)
from authentik.events.logs import LogEvent, capture_logs
from authentik.events.models import SystemTask
from authentik.events.utils import cleanse_dict
from authentik.flows.models import FlowToken, Stage
from authentik.lib.models import SerializerModel
@ -77,6 +76,7 @@ from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
from authentik.rbac.models import Role
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
from authentik.stages.authenticator_webauthn.models import WebAuthnDeviceType
from authentik.tasks.models import Task
from authentik.tenants.models import Tenant
# Context set when the serializer is created in a blueprint context
@ -118,7 +118,7 @@ def excluded_models() -> list[type[Model]]:
SCIMProviderGroup,
SCIMProviderUser,
Tenant,
SystemTask,
Task,
ConnectionToken,
AuthorizationCode,
AccessToken,
@ -384,7 +384,7 @@ class Importer:
def _apply_models(self, raise_errors=False) -> bool:
"""Apply (create/update) models yaml"""
self.__pk_map = {}
for entry in self._import.entries:
for entry in self._import.iter_entries():
model_app_label, model_name = entry.get_model(self._import).split(".")
try:
model: type[SerializerModel] = registry.get_model(model_app_label, model_name)

View File

@ -44,7 +44,7 @@ class ApplyBlueprintMetaSerializer(PassiveSerializer):
return MetaResult()
LOGGER.debug("Applying blueprint from meta model", blueprint=self.blueprint_instance)
apply_blueprint(str(self.blueprint_instance.pk))
apply_blueprint(self.blueprint_instance.pk)
return MetaResult()

View File

@ -4,12 +4,17 @@ from dataclasses import asdict, dataclass, field
from hashlib import sha512
from pathlib import Path
from sys import platform
from uuid import UUID
from dacite.core import from_dict
from django.conf import settings
from django.db import DatabaseError, InternalError, ProgrammingError
from django.utils.text import slugify
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask, CurrentTaskNotFound
from dramatiq.actor import actor
from dramatiq.middleware import Middleware
from structlog.stdlib import get_logger
from watchdog.events import (
FileCreatedEvent,
@ -31,15 +36,13 @@ from authentik.blueprints.v1.importer import Importer
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
from authentik.blueprints.v1.oci import OCI_PREFIX
from authentik.events.logs import capture_logs
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask, prefill_task
from authentik.events.utils import sanitize_dict
from authentik.lib.config import CONFIG
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
from authentik.tasks.schedules.models import Schedule
from authentik.tenants.models import Tenant
LOGGER = get_logger()
_file_watcher_started = False
@dataclass
@ -53,22 +56,21 @@ class BlueprintFile:
meta: BlueprintMetadata | None = field(default=None)
def start_blueprint_watcher():
"""Start blueprint watcher, if it's not running already."""
# This function might be called twice since it's called on celery startup
class BlueprintWatcherMiddleware(Middleware):
def start_blueprint_watcher(self):
"""Start blueprint watcher"""
observer = Observer()
kwargs = {}
if platform.startswith("linux"):
kwargs["event_filter"] = (FileCreatedEvent, FileModifiedEvent)
observer.schedule(
BlueprintEventHandler(), CONFIG.get("blueprints_dir"), recursive=True, **kwargs
)
observer.start()
global _file_watcher_started # noqa: PLW0603
if _file_watcher_started:
return
observer = Observer()
kwargs = {}
if platform.startswith("linux"):
kwargs["event_filter"] = (FileCreatedEvent, FileModifiedEvent)
observer.schedule(
BlueprintEventHandler(), CONFIG.get("blueprints_dir"), recursive=True, **kwargs
)
observer.start()
_file_watcher_started = True
def after_worker_boot(self, broker, worker):
if not settings.TEST:
self.start_blueprint_watcher()
class BlueprintEventHandler(FileSystemEventHandler):
@ -92,7 +94,7 @@ class BlueprintEventHandler(FileSystemEventHandler):
LOGGER.debug("new blueprint file created, starting discovery")
for tenant in Tenant.objects.filter(ready=True):
with tenant:
blueprints_discovery.delay()
Schedule.dispatch_by_actor(blueprints_discovery)
def on_modified(self, event: FileSystemEvent):
"""Process file modification"""
@ -103,14 +105,14 @@ class BlueprintEventHandler(FileSystemEventHandler):
with tenant:
for instance in BlueprintInstance.objects.filter(path=rel_path, enabled=True):
LOGGER.debug("modified blueprint file, starting apply", instance=instance)
apply_blueprint.delay(instance.pk.hex)
apply_blueprint.send_with_options(args=(instance.pk,), rel_obj=instance)
@CELERY_APP.task(
@actor(
description=_("Find blueprints as `blueprints_find` does, but return a safe dict."),
throws=(DatabaseError, ProgrammingError, InternalError),
)
def blueprints_find_dict():
"""Find blueprints as `blueprints_find` does, but return a safe dict"""
blueprints = []
for blueprint in blueprints_find():
blueprints.append(sanitize_dict(asdict(blueprint)))
@ -146,21 +148,19 @@ def blueprints_find() -> list[BlueprintFile]:
return blueprints
@CELERY_APP.task(
throws=(DatabaseError, ProgrammingError, InternalError), base=SystemTask, bind=True
@actor(
description=_("Find blueprints and check if they need to be created in the database."),
throws=(DatabaseError, ProgrammingError, InternalError),
)
@prefill_task
def blueprints_discovery(self: SystemTask, path: str | None = None):
"""Find blueprints and check if they need to be created in the database"""
def blueprints_discovery(path: str | None = None):
self: Task = CurrentTask.get_task()
count = 0
for blueprint in blueprints_find():
if path and blueprint.path != path:
continue
check_blueprint_v1_file(blueprint)
count += 1
self.set_status(
TaskStatus.SUCCESSFUL, _("Successfully imported {count} files.".format(count=count))
)
self.info(f"Successfully imported {count} files.")
def check_blueprint_v1_file(blueprint: BlueprintFile):
@ -187,22 +187,26 @@ def check_blueprint_v1_file(blueprint: BlueprintFile):
)
if instance.last_applied_hash != blueprint.hash:
LOGGER.info("Applying blueprint due to changed file", instance=instance, path=instance.path)
apply_blueprint.delay(str(instance.pk))
apply_blueprint.send_with_options(args=(instance.pk,), rel_obj=instance)
@CELERY_APP.task(
bind=True,
base=SystemTask,
)
def apply_blueprint(self: SystemTask, instance_pk: str):
"""Apply single blueprint"""
self.save_on_success = False
@actor(description=_("Apply single blueprint."))
def apply_blueprint(instance_pk: UUID):
try:
self: Task = CurrentTask.get_task()
except CurrentTaskNotFound:
self = Task()
self.set_uid(str(instance_pk))
instance: BlueprintInstance | None = None
try:
instance: BlueprintInstance = BlueprintInstance.objects.filter(pk=instance_pk).first()
if not instance or not instance.enabled:
if not instance:
self.warning(f"Could not find blueprint {instance_pk}, skipping")
return
self.set_uid(slugify(instance.name))
if not instance.enabled:
self.info(f"Blueprint {instance.name} is disabled, skipping")
return
blueprint_content = instance.retrieve()
file_hash = sha512(blueprint_content.encode()).hexdigest()
importer = Importer.from_string(blueprint_content, instance.context)
@ -212,19 +216,18 @@ def apply_blueprint(self: SystemTask, instance_pk: str):
if not valid:
instance.status = BlueprintInstanceStatus.ERROR
instance.save()
self.set_status(TaskStatus.ERROR, *logs)
self.logs(logs)
return
with capture_logs() as logs:
applied = importer.apply()
if not applied:
instance.status = BlueprintInstanceStatus.ERROR
instance.save()
self.set_status(TaskStatus.ERROR, *logs)
self.logs(logs)
return
instance.status = BlueprintInstanceStatus.SUCCESSFUL
instance.last_applied_hash = file_hash
instance.last_applied = now()
self.set_status(TaskStatus.SUCCESSFUL)
except (
OSError,
DatabaseError,
@ -235,15 +238,14 @@ def apply_blueprint(self: SystemTask, instance_pk: str):
) as exc:
if instance:
instance.status = BlueprintInstanceStatus.ERROR
self.set_error(exc)
self.error(exc)
finally:
if instance:
instance.save()
@CELERY_APP.task()
@actor(description=_("Remove blueprints which couldn't be fetched."))
def clear_failed_blueprints():
"""Remove blueprints which couldn't be fetched"""
# Exclude OCI blueprints as those might be temporarily unavailable
for blueprint in BlueprintInstance.objects.exclude(path__startswith=OCI_PREFIX):
try:

View File

@ -9,6 +9,7 @@ class AuthentikBrandsConfig(ManagedAppConfig):
name = "authentik.brands"
label = "authentik_brands"
verbose_name = "authentik Brands"
default = True
mountpoints = {
"authentik.brands.urls_root": "",
}

View File

@ -1,8 +1,6 @@
"""Authenticator Devices API Views"""
from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from drf_spectacular.utils import extend_schema
from guardian.shortcuts import get_objects_for_user
from rest_framework.fields import (
BooleanField,
@ -15,6 +13,7 @@ from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from authentik.core.api.users import ParamUserSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import EndpointDevice
from authentik.stages.authenticator import device_classes, devices_for_user
@ -23,7 +22,7 @@ from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
class DeviceSerializer(MetaNameSerializer):
"""Serializer for Duo authenticator devices"""
"""Serializer for authenticator devices"""
pk = CharField()
name = CharField()
@ -33,22 +32,27 @@ class DeviceSerializer(MetaNameSerializer):
last_updated = DateTimeField(read_only=True)
last_used = DateTimeField(read_only=True, allow_null=True)
extra_description = SerializerMethodField()
external_id = SerializerMethodField()
def get_type(self, instance: Device) -> str:
"""Get type of device"""
return instance._meta.label
def get_extra_description(self, instance: Device) -> str:
def get_extra_description(self, instance: Device) -> str | None:
"""Get extra description"""
if isinstance(instance, WebAuthnDevice):
return (
instance.device_type.description
if instance.device_type
else _("Extra description not available")
)
return instance.device_type.description if instance.device_type else None
if isinstance(instance, EndpointDevice):
return instance.data.get("deviceSignals", {}).get("deviceModel")
return ""
return None
def get_external_id(self, instance: Device) -> str | None:
"""Get external Device ID"""
if isinstance(instance, WebAuthnDevice):
return instance.device_type.aaguid if instance.device_type else None
if isinstance(instance, EndpointDevice):
return instance.data.get("deviceSignals", {}).get("deviceModel")
return None
class DeviceViewSet(ViewSet):
@ -57,7 +61,6 @@ class DeviceViewSet(ViewSet):
serializer_class = DeviceSerializer
permission_classes = [IsAuthenticated]
@extend_schema(responses={200: DeviceSerializer(many=True)})
def list(self, request: Request) -> Response:
"""Get all devices for current user"""
devices = devices_for_user(request.user)
@ -79,18 +82,11 @@ class AdminDeviceViewSet(ViewSet):
yield from device_set
@extend_schema(
parameters=[
OpenApiParameter(
name="user",
location=OpenApiParameter.QUERY,
type=OpenApiTypes.INT,
)
],
parameters=[ParamUserSerializer],
responses={200: DeviceSerializer(many=True)},
)
def list(self, request: Request) -> Response:
"""Get all devices for current user"""
kwargs = {}
if "user" in request.query_params:
kwargs = {"user": request.query_params["user"]}
return Response(DeviceSerializer(self.get_devices(**kwargs), many=True).data)
args = ParamUserSerializer(data=request.query_params)
args.is_valid(raise_exception=True)
return Response(DeviceSerializer(self.get_devices(**args.validated_data), many=True).data)

View File

@ -90,6 +90,12 @@ from authentik.stages.email.utils import TemplateEmailMessage
LOGGER = get_logger()
class ParamUserSerializer(PassiveSerializer):
"""Partial serializer for query parameters to select a user"""
user = PrimaryKeyRelatedField(queryset=User.objects.all().exclude_anonymous(), required=False)
class UserGroupSerializer(ModelSerializer):
"""Simplified Group Serializer for user's groups"""
@ -386,8 +392,23 @@ class UserViewSet(UsedByMixin, ModelViewSet):
queryset = User.objects.none()
ordering = ["username"]
serializer_class = UserSerializer
search_fields = ["username", "name", "is_active", "email", "uuid", "attributes"]
filterset_class = UsersFilter
search_fields = ["username", "name", "is_active", "email", "uuid", "attributes"]
def get_ql_fields(self):
from djangoql.schema import BoolField, StrField
from authentik.enterprise.search.fields import ChoiceSearchField, JSONSearchField
return [
StrField(User, "username"),
StrField(User, "name"),
StrField(User, "email"),
StrField(User, "path"),
BoolField(User, "is_active", nullable=True),
ChoiceSearchField(User, "type"),
JSONSearchField(User, "attributes", suggest_nested=False),
]
def get_queryset(self):
base_qs = User.objects.all().exclude_anonymous()

View File

@ -2,6 +2,7 @@
from typing import Any
from django.db import models
from django.db.models import Model
from drf_spectacular.extensions import OpenApiSerializerFieldExtension
from drf_spectacular.plumbing import build_basic_type
@ -30,7 +31,27 @@ def is_dict(value: Any):
raise ValidationError("Value must be a dictionary, and not have any duplicate keys.")
class JSONDictField(JSONField):
"""JSON Field which only allows dictionaries"""
default_validators = [is_dict]
class JSONExtension(OpenApiSerializerFieldExtension):
"""Generate API Schema for JSON fields as"""
target_class = "authentik.core.api.utils.JSONDictField"
def map_serializer_field(self, auto_schema, direction):
return build_basic_type(OpenApiTypes.OBJECT)
class ModelSerializer(BaseModelSerializer):
# By default, JSON fields we have are used to store dictionaries
serializer_field_mapping = BaseModelSerializer.serializer_field_mapping.copy()
serializer_field_mapping[models.JSONField] = JSONDictField
def create(self, validated_data):
instance = super().create(validated_data)
@ -71,21 +92,6 @@ class ModelSerializer(BaseModelSerializer):
return instance
class JSONDictField(JSONField):
"""JSON Field which only allows dictionaries"""
default_validators = [is_dict]
class JSONExtension(OpenApiSerializerFieldExtension):
"""Generate API Schema for JSON fields as"""
target_class = "authentik.core.api.utils.JSONDictField"
def map_serializer_field(self, auto_schema, direction):
return build_basic_type(OpenApiTypes.OBJECT)
class PassiveSerializer(Serializer):
"""Base serializer class which doesn't implement create/update methods"""

View File

@ -1,8 +1,7 @@
"""authentik core app config"""
from django.conf import settings
from authentik.blueprints.apps import ManagedAppConfig
from authentik.tasks.schedules.lib import ScheduleSpec
class AuthentikCoreConfig(ManagedAppConfig):
@ -14,14 +13,6 @@ class AuthentikCoreConfig(ManagedAppConfig):
mountpoint = ""
default = True
@ManagedAppConfig.reconcile_global
def debug_worker_hook(self):
"""Dispatch startup tasks inline when debugging"""
if settings.DEBUG:
from authentik.root.celery import worker_ready_hook
worker_ready_hook()
@ManagedAppConfig.reconcile_tenant
def source_inbuilt(self):
"""Reconcile inbuilt source"""
@ -34,3 +25,18 @@ class AuthentikCoreConfig(ManagedAppConfig):
},
managed=Source.MANAGED_INBUILT,
)
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.core.tasks import clean_expired_models, clean_temporary_users
return [
ScheduleSpec(
actor=clean_expired_models,
crontab="2-59/5 * * * *",
),
ScheduleSpec(
actor=clean_temporary_users,
crontab="9-59/5 * * * *",
),
]

View File

@ -1,21 +0,0 @@
"""Run bootstrap tasks"""
from django.core.management.base import BaseCommand
from django_tenants.utils import get_public_schema_name
from authentik.root.celery import _get_startup_tasks_all_tenants, _get_startup_tasks_default_tenant
from authentik.tenants.models import Tenant
class Command(BaseCommand):
"""Run bootstrap tasks to ensure certain objects are created"""
def handle(self, **options):
for task in _get_startup_tasks_default_tenant():
with Tenant.objects.get(schema_name=get_public_schema_name()):
task()
for task in _get_startup_tasks_all_tenants():
for tenant in Tenant.objects.filter(ready=True):
with tenant:
task()

View File

@ -13,7 +13,6 @@ class Command(TenantCommand):
parser.add_argument("usernames", nargs="*", type=str)
def handle_per_tenant(self, **options):
print(options)
new_type = UserTypes(options["type"])
qs = (
User.objects.exclude_anonymous()

View File

@ -1,47 +0,0 @@
"""Run worker"""
from sys import exit as sysexit
from tempfile import tempdir
from celery.apps.worker import Worker
from django.core.management.base import BaseCommand
from django.db import close_old_connections
from structlog.stdlib import get_logger
from authentik.lib.config import CONFIG
from authentik.lib.debug import start_debug_server
from authentik.root.celery import CELERY_APP
LOGGER = get_logger()
class Command(BaseCommand):
"""Run worker"""
def add_arguments(self, parser):
parser.add_argument(
"-b",
"--beat",
action="store_false",
help="When set, this worker will _not_ run Beat (scheduled) tasks",
)
def handle(self, **options):
LOGGER.debug("Celery options", **options)
close_old_connections()
start_debug_server()
worker: Worker = CELERY_APP.Worker(
no_color=False,
quiet=True,
optimization="fair",
autoscale=(CONFIG.get_int("worker.concurrency"), 1),
task_events=True,
beat=options.get("beat", True),
schedule_filename=f"{tempdir}/celerybeat-schedule",
queues=["authentik", "authentik_scheduled", "authentik_events"],
)
for task in CELERY_APP.tasks:
LOGGER.debug("Registered task", task=task)
worker.start()
sysexit(worker.exitcode)

View File

@ -18,7 +18,7 @@ from django.http import HttpRequest
from django.utils.functional import SimpleLazyObject, cached_property
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_cte import CTEQuerySet, With
from django_cte import CTE, with_cte
from guardian.conf import settings
from guardian.mixins import GuardianUserMixin
from model_utils.managers import InheritanceManager
@ -136,7 +136,7 @@ class AttributesMixin(models.Model):
return instance, False
class GroupQuerySet(CTEQuerySet):
class GroupQuerySet(QuerySet):
def with_children_recursive(self):
"""Recursively get all groups that have the current queryset as parents
or are indirectly related."""
@ -165,9 +165,9 @@ class GroupQuerySet(CTEQuerySet):
)
# Build the recursive query, see above
cte = With.recursive(make_cte)
cte = CTE.recursive(make_cte)
# Return the result, as a usable queryset for Group.
return cte.join(Group, group_uuid=cte.col.group_uuid).with_cte(cte)
return with_cte(cte, select=cte.join(Group, group_uuid=cte.col.group_uuid))
class Group(SerializerModel, AttributesMixin):
@ -1082,6 +1082,12 @@ class AuthenticatedSession(SerializerModel):
user = models.ForeignKey(User, on_delete=models.CASCADE)
@property
def serializer(self) -> type[Serializer]:
from authentik.core.api.authenticated_sessions import AuthenticatedSessionSerializer
return AuthenticatedSessionSerializer
class Meta:
verbose_name = _("Authenticated Session")
verbose_name_plural = _("Authenticated Sessions")

View File

@ -3,6 +3,9 @@
from datetime import datetime, timedelta
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask
from dramatiq.actor import actor
from structlog.stdlib import get_logger
from authentik.core.models import (
@ -11,17 +14,14 @@ from authentik.core.models import (
ExpiringModel,
User,
)
from authentik.events.system_tasks import SystemTask, TaskStatus, prefill_task
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def clean_expired_models(self: SystemTask):
"""Remove expired objects"""
messages = []
@actor(description=_("Remove expired objects."))
def clean_expired_models():
self: Task = CurrentTask.get_task()
for cls in ExpiringModel.__subclasses__():
cls: ExpiringModel
objects = (
@ -31,16 +31,13 @@ def clean_expired_models(self: SystemTask):
for obj in objects:
obj.expire_action()
LOGGER.debug("Expired models", model=cls, amount=amount)
messages.append(f"Expired {amount} {cls._meta.verbose_name_plural}")
self.set_status(TaskStatus.SUCCESSFUL, *messages)
self.info(f"Expired {amount} {cls._meta.verbose_name_plural}")
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def clean_temporary_users(self: SystemTask):
"""Remove temporary users created by SAML Sources"""
@actor(description=_("Remove temporary users created by SAML Sources."))
def clean_temporary_users():
self: Task = CurrentTask.get_task()
_now = datetime.now()
messages = []
deleted_users = 0
for user in User.objects.filter(**{f"attributes__{USER_ATTRIBUTE_GENERATED}": True}):
if not user.attributes.get(USER_ATTRIBUTE_EXPIRES):
@ -52,5 +49,4 @@ def clean_temporary_users(self: SystemTask):
LOGGER.debug("User is expired and will be deleted.", user=user, delta=delta)
user.delete()
deleted_users += 1
messages.append(f"Successfully deleted {deleted_users} users.")
self.set_status(TaskStatus.SUCCESSFUL, *messages)
self.info(f"Successfully deleted {deleted_users} users.")

View File

@ -114,6 +114,7 @@ class TestApplicationsAPI(APITestCase):
self.assertJSONEqual(
response.content.decode(),
{
"autocomplete": {},
"pagination": {
"next": 0,
"previous": 0,
@ -167,6 +168,7 @@ class TestApplicationsAPI(APITestCase):
self.assertJSONEqual(
response.content.decode(),
{
"autocomplete": {},
"pagination": {
"next": 0,
"previous": 0,

View File

@ -36,7 +36,7 @@ class TestTasks(APITestCase):
expires=now(), user=get_anonymous_user(), intent=TokenIntents.INTENT_API
)
key = token.key
clean_expired_models.delay().get()
clean_expired_models.send()
token.refresh_from_db()
self.assertNotEqual(key, token.key)
@ -50,5 +50,5 @@ class TestTasks(APITestCase):
USER_ATTRIBUTE_EXPIRES: mktime(now().timetuple()),
},
)
clean_temporary_users.delay().get()
clean_temporary_users.send()
self.assertFalse(User.objects.filter(username=username))

View File

@ -4,6 +4,8 @@ from datetime import UTC, datetime
from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.generators import generate_id
from authentik.lib.utils.time import fqdn_rand
from authentik.tasks.schedules.lib import ScheduleSpec
MANAGED_KEY = "goauthentik.io/crypto/jwt-managed"
@ -67,3 +69,14 @@ class AuthentikCryptoConfig(ManagedAppConfig):
"key_data": builder.private_key,
},
)
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.crypto.tasks import certificate_discovery
return [
ScheduleSpec(
actor=certificate_discovery,
crontab=f"{fqdn_rand('crypto_certificate_discovery')} * * * *",
),
]

View File

@ -1,13 +0,0 @@
"""Crypto task Settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"crypto_certificate_discovery": {
"task": "authentik.crypto.tasks.certificate_discovery",
"schedule": crontab(minute=fqdn_rand("crypto_certificate_discovery"), hour="*"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -7,13 +7,13 @@ from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509.base import load_pem_x509_certificate
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask
from dramatiq.actor import actor
from structlog.stdlib import get_logger
from authentik.crypto.models import CertificateKeyPair
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask, prefill_task
from authentik.lib.config import CONFIG
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
LOGGER = get_logger()
@ -36,10 +36,9 @@ def ensure_certificate_valid(body: str):
return body
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def certificate_discovery(self: SystemTask):
"""Discover, import and update certificates from the filesystem"""
@actor(description=_("Discover, import and update certificates from the filesystem."))
def certificate_discovery():
self: Task = CurrentTask.get_task()
certs = {}
private_keys = {}
discovered = 0
@ -84,6 +83,4 @@ def certificate_discovery(self: SystemTask):
dirty = True
if dirty:
cert.save()
self.set_status(
TaskStatus.SUCCESSFUL, _("Successfully imported {count} files.".format(count=discovered))
)
self.info(f"Successfully imported {discovered} files.")

View File

@ -338,7 +338,7 @@ class TestCrypto(APITestCase):
with open(f"{temp_dir}/foo.bar/privkey.pem", "w+", encoding="utf-8") as _key:
_key.write(builder.private_key)
with CONFIG.patch("cert_discovery_dir", temp_dir):
certificate_discovery()
certificate_discovery.send()
keypair: CertificateKeyPair = CertificateKeyPair.objects.filter(
managed=MANAGED_DISCOVERED % "foo"
).first()

View File

@ -3,6 +3,8 @@
from django.conf import settings
from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.utils.time import fqdn_rand
from authentik.tasks.schedules.lib import ScheduleSpec
class EnterpriseConfig(ManagedAppConfig):
@ -26,3 +28,14 @@ class AuthentikEnterpriseConfig(EnterpriseConfig):
from authentik.enterprise.license import LicenseKey
return LicenseKey.cached_summary().status.is_valid
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.enterprise.tasks import enterprise_update_usage
return [
ScheduleSpec(
actor=enterprise_update_usage,
crontab=f"{fqdn_rand('enterprise_update_usage')} */2 * * *",
),
]

View File

@ -1,6 +1,8 @@
"""authentik Unique Password policy app config"""
from authentik.enterprise.apps import EnterpriseConfig
from authentik.lib.utils.time import fqdn_rand
from authentik.tasks.schedules.lib import ScheduleSpec
class AuthentikEnterprisePoliciesUniquePasswordConfig(EnterpriseConfig):
@ -8,3 +10,21 @@ class AuthentikEnterprisePoliciesUniquePasswordConfig(EnterpriseConfig):
label = "authentik_policies_unique_password"
verbose_name = "authentik Enterprise.Policies.Unique Password"
default = True
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.enterprise.policies.unique_password.tasks import (
check_and_purge_password_history,
trim_password_histories,
)
return [
ScheduleSpec(
actor=trim_password_histories,
crontab=f"{fqdn_rand('policies_unique_password_trim')} */12 * * *",
),
ScheduleSpec(
actor=check_and_purge_password_history,
crontab=f"{fqdn_rand('policies_unique_password_purge')} */24 * * *",
),
]

View File

@ -1,20 +0,0 @@
"""Unique Password Policy settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"policies_unique_password_trim_history": {
"task": "authentik.enterprise.policies.unique_password.tasks.trim_password_histories",
"schedule": crontab(minute=fqdn_rand("policies_unique_password_trim"), hour="*/12"),
"options": {"queue": "authentik_scheduled"},
},
"policies_unique_password_check_purge": {
"task": (
"authentik.enterprise.policies.unique_password.tasks.check_and_purge_password_history"
),
"schedule": crontab(minute=fqdn_rand("policies_unique_password_purge"), hour="*/24"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -1,35 +1,37 @@
from django.db.models.aggregates import Count
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask
from dramatiq.actor import actor
from structlog import get_logger
from authentik.enterprise.policies.unique_password.models import (
UniquePasswordPolicy,
UserPasswordHistory,
)
from authentik.events.system_tasks import SystemTask, TaskStatus, prefill_task
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def check_and_purge_password_history(self: SystemTask):
"""Check if any UniquePasswordPolicy exists, and if not, purge the password history table.
This is run on a schedule instead of being triggered by policy binding deletion.
"""
@actor(
description=_(
"Check if any UniquePasswordPolicy exists, and if not, purge the password history table."
)
)
def check_and_purge_password_history():
self: Task = CurrentTask.get_task()
if not UniquePasswordPolicy.objects.exists():
UserPasswordHistory.objects.all().delete()
LOGGER.debug("Purged UserPasswordHistory table as no policies are in use")
self.set_status(TaskStatus.SUCCESSFUL, "Successfully purged UserPasswordHistory")
self.info("Successfully purged UserPasswordHistory")
return
self.set_status(
TaskStatus.SUCCESSFUL, "Not purging password histories, a unique password policy exists"
)
self.info("Not purging password histories, a unique password policy exists")
@CELERY_APP.task(bind=True, base=SystemTask)
def trim_password_histories(self: SystemTask):
@actor(description=_("Remove user password history that are too old."))
def trim_password_histories():
"""Removes rows from UserPasswordHistory older than
the `n` most recent entries.
@ -37,6 +39,8 @@ def trim_password_histories(self: SystemTask):
UniquePasswordPolicy policies.
"""
self: Task = CurrentTask.get_task()
# No policy, we'll let the cleanup above do its thing
if not UniquePasswordPolicy.objects.exists():
return
@ -63,4 +67,4 @@ def trim_password_histories(self: SystemTask):
num_deleted, _ = UserPasswordHistory.objects.exclude(pk__in=all_pks_to_keep).delete()
LOGGER.debug("Deleted stale password history records", count=num_deleted)
self.set_status(TaskStatus.SUCCESSFUL, f"Delete {num_deleted} stale password history records")
self.info(f"Delete {num_deleted} stale password history records")

View File

@ -76,7 +76,7 @@ class TestCheckAndPurgePasswordHistory(TestCase):
self.assertTrue(UserPasswordHistory.objects.exists())
# Run the task - should purge since no policy is in use
check_and_purge_password_history()
check_and_purge_password_history.send()
# Verify the table is empty
self.assertFalse(UserPasswordHistory.objects.exists())
@ -99,7 +99,7 @@ class TestCheckAndPurgePasswordHistory(TestCase):
self.assertTrue(UserPasswordHistory.objects.exists())
# Run the task - should NOT purge since a policy is in use
check_and_purge_password_history()
check_and_purge_password_history.send()
# Verify the entries still exist
self.assertTrue(UserPasswordHistory.objects.exists())
@ -119,17 +119,17 @@ class TestTrimPasswordHistory(TestCase):
[
UserPasswordHistory(
user=self.user,
old_password="hunter1", # nosec B106
old_password="hunter1", # nosec
created_at=_now - timedelta(days=3),
),
UserPasswordHistory(
user=self.user,
old_password="hunter2", # nosec B106
old_password="hunter2", # nosec
created_at=_now - timedelta(days=2),
),
UserPasswordHistory(
user=self.user,
old_password="hunter3", # nosec B106
old_password="hunter3", # nosec
created_at=_now,
),
]
@ -142,7 +142,7 @@ class TestTrimPasswordHistory(TestCase):
enabled=True,
order=0,
)
trim_password_histories.delay()
trim_password_histories.send()
user_pwd_history_qs = UserPasswordHistory.objects.filter(user=self.user)
self.assertEqual(len(user_pwd_history_qs), 1)
@ -159,7 +159,7 @@ class TestTrimPasswordHistory(TestCase):
enabled=False,
order=0,
)
trim_password_histories.delay()
trim_password_histories.send()
self.assertTrue(UserPasswordHistory.objects.filter(user=self.user).exists())
def test_trim_password_history_fewer_records_than_maximum_is_no_op(self):
@ -174,5 +174,5 @@ class TestTrimPasswordHistory(TestCase):
enabled=True,
order=0,
)
trim_password_histories.delay()
trim_password_histories.send()
self.assertTrue(UserPasswordHistory.objects.filter(user=self.user).exists())

View File

@ -55,5 +55,5 @@ class GoogleWorkspaceProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixi
]
search_fields = ["name"]
ordering = ["name"]
sync_single_task = google_workspace_sync
sync_task = google_workspace_sync
sync_objects_task = google_workspace_sync_objects

View File

@ -7,6 +7,7 @@ from django.db import models
from django.db.models import QuerySet
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import Actor
from google.oauth2.service_account import Credentials
from rest_framework.serializers import Serializer
@ -110,6 +111,12 @@ class GoogleWorkspaceProvider(OutgoingSyncProvider, BackchannelProvider):
help_text=_("Property mappings used for group creation/updating."),
)
@property
def sync_actor(self) -> Actor:
from authentik.enterprise.providers.google_workspace.tasks import google_workspace_sync
return google_workspace_sync
def client_for_model(
self,
model: type[User | Group | GoogleWorkspaceProviderUser | GoogleWorkspaceProviderGroup],

View File

@ -1,13 +0,0 @@
"""Google workspace provider task Settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"providers_google_workspace_sync": {
"task": "authentik.enterprise.providers.google_workspace.tasks.google_workspace_sync_all",
"schedule": crontab(minute=fqdn_rand("google_workspace_sync_all"), hour="*/4"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -2,15 +2,13 @@
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProvider
from authentik.enterprise.providers.google_workspace.tasks import (
google_workspace_sync,
google_workspace_sync_direct,
google_workspace_sync_m2m,
google_workspace_sync_direct_dispatch,
google_workspace_sync_m2m_dispatch,
)
from authentik.lib.sync.outgoing.signals import register_signals
register_signals(
GoogleWorkspaceProvider,
task_sync_single=google_workspace_sync,
task_sync_direct=google_workspace_sync_direct,
task_sync_m2m=google_workspace_sync_m2m,
task_sync_direct_dispatch=google_workspace_sync_direct_dispatch,
task_sync_m2m_dispatch=google_workspace_sync_m2m_dispatch,
)

View File

@ -1,37 +1,48 @@
"""Google Provider tasks"""
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import actor
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProvider
from authentik.events.system_tasks import SystemTask
from authentik.lib.sync.outgoing.exceptions import TransientSyncException
from authentik.lib.sync.outgoing.tasks import SyncTasks
from authentik.root.celery import CELERY_APP
sync_tasks = SyncTasks(GoogleWorkspaceProvider)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(description=_("Sync Google Workspace provider objects."))
def google_workspace_sync_objects(*args, **kwargs):
return sync_tasks.sync_objects(*args, **kwargs)
@CELERY_APP.task(
base=SystemTask, bind=True, autoretry_for=(TransientSyncException,), retry_backoff=True
)
def google_workspace_sync(self, provider_pk: int, *args, **kwargs):
@actor(description=_("Full sync for Google Workspace provider."))
def google_workspace_sync(provider_pk: int, *args, **kwargs):
"""Run full sync for Google Workspace provider"""
return sync_tasks.sync_single(self, provider_pk, google_workspace_sync_objects)
return sync_tasks.sync(provider_pk, google_workspace_sync_objects)
@CELERY_APP.task()
def google_workspace_sync_all():
return sync_tasks.sync_all(google_workspace_sync)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(description=_("Sync a direct object (user, group) for Google Workspace provider."))
def google_workspace_sync_direct(*args, **kwargs):
return sync_tasks.sync_signal_direct(*args, **kwargs)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(
description=_(
"Dispatch syncs for a direct object (user, group) for Google Workspace providers."
)
)
def google_workspace_sync_direct_dispatch(*args, **kwargs):
return sync_tasks.sync_signal_direct_dispatch(google_workspace_sync_direct, *args, **kwargs)
@actor(description=_("Sync a related object (memberships) for Google Workspace provider."))
def google_workspace_sync_m2m(*args, **kwargs):
return sync_tasks.sync_signal_m2m(*args, **kwargs)
@actor(
description=_(
"Dispatch syncs for a related object (memberships) for Google Workspace providers."
)
)
def google_workspace_sync_m2m_dispatch(*args, **kwargs):
return sync_tasks.sync_signal_m2m_dispatch(google_workspace_sync_m2m, *args, **kwargs)

View File

@ -324,7 +324,7 @@ class GoogleWorkspaceGroupTests(TestCase):
"authentik.enterprise.providers.google_workspace.models.GoogleWorkspaceProvider.google_credentials",
MagicMock(return_value={"developerKey": self.api_key, "http": http}),
):
google_workspace_sync.delay(self.provider.pk).get()
google_workspace_sync.send(self.provider.pk).get_result()
self.assertTrue(
GoogleWorkspaceProviderGroup.objects.filter(
group=different_group, provider=self.provider

View File

@ -302,7 +302,7 @@ class GoogleWorkspaceUserTests(TestCase):
"authentik.enterprise.providers.google_workspace.models.GoogleWorkspaceProvider.google_credentials",
MagicMock(return_value={"developerKey": self.api_key, "http": http}),
):
google_workspace_sync.delay(self.provider.pk).get()
google_workspace_sync.send(self.provider.pk).get_result()
self.assertTrue(
GoogleWorkspaceProviderUser.objects.filter(
user=different_user, provider=self.provider

View File

@ -53,5 +53,5 @@ class MicrosoftEntraProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin
]
search_fields = ["name"]
ordering = ["name"]
sync_single_task = microsoft_entra_sync
sync_task = microsoft_entra_sync
sync_objects_task = microsoft_entra_sync_objects

View File

@ -8,6 +8,7 @@ from django.db import models
from django.db.models import QuerySet
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import Actor
from rest_framework.serializers import Serializer
from authentik.core.models import (
@ -99,6 +100,12 @@ class MicrosoftEntraProvider(OutgoingSyncProvider, BackchannelProvider):
help_text=_("Property mappings used for group creation/updating."),
)
@property
def sync_actor(self) -> Actor:
from authentik.enterprise.providers.microsoft_entra.tasks import microsoft_entra_sync
return microsoft_entra_sync
def client_for_model(
self,
model: type[User | Group | MicrosoftEntraProviderUser | MicrosoftEntraProviderGroup],

View File

@ -1,13 +0,0 @@
"""Microsoft Entra provider task Settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"providers_microsoft_entra_sync": {
"task": "authentik.enterprise.providers.microsoft_entra.tasks.microsoft_entra_sync_all",
"schedule": crontab(minute=fqdn_rand("microsoft_entra_sync_all"), hour="*/4"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -2,15 +2,13 @@
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider
from authentik.enterprise.providers.microsoft_entra.tasks import (
microsoft_entra_sync,
microsoft_entra_sync_direct,
microsoft_entra_sync_m2m,
microsoft_entra_sync_direct_dispatch,
microsoft_entra_sync_m2m_dispatch,
)
from authentik.lib.sync.outgoing.signals import register_signals
register_signals(
MicrosoftEntraProvider,
task_sync_single=microsoft_entra_sync,
task_sync_direct=microsoft_entra_sync_direct,
task_sync_m2m=microsoft_entra_sync_m2m,
task_sync_direct_dispatch=microsoft_entra_sync_direct_dispatch,
task_sync_m2m_dispatch=microsoft_entra_sync_m2m_dispatch,
)

View File

@ -1,37 +1,46 @@
"""Microsoft Entra Provider tasks"""
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import actor
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider
from authentik.events.system_tasks import SystemTask
from authentik.lib.sync.outgoing.exceptions import TransientSyncException
from authentik.lib.sync.outgoing.tasks import SyncTasks
from authentik.root.celery import CELERY_APP
sync_tasks = SyncTasks(MicrosoftEntraProvider)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(description=_("Sync Microsoft Entra provider objects."))
def microsoft_entra_sync_objects(*args, **kwargs):
return sync_tasks.sync_objects(*args, **kwargs)
@CELERY_APP.task(
base=SystemTask, bind=True, autoretry_for=(TransientSyncException,), retry_backoff=True
)
def microsoft_entra_sync(self, provider_pk: int, *args, **kwargs):
@actor(description=_("Full sync for Microsoft Entra provider."))
def microsoft_entra_sync(provider_pk: int, *args, **kwargs):
"""Run full sync for Microsoft Entra provider"""
return sync_tasks.sync_single(self, provider_pk, microsoft_entra_sync_objects)
return sync_tasks.sync(provider_pk, microsoft_entra_sync_objects)
@CELERY_APP.task()
def microsoft_entra_sync_all():
return sync_tasks.sync_all(microsoft_entra_sync)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(description=_("Sync a direct object (user, group) for Microsoft Entra provider."))
def microsoft_entra_sync_direct(*args, **kwargs):
return sync_tasks.sync_signal_direct(*args, **kwargs)
@CELERY_APP.task(autoretry_for=(TransientSyncException,), retry_backoff=True)
@actor(
description=_("Dispatch syncs for a direct object (user, group) for Microsoft Entra providers.")
)
def microsoft_entra_sync_direct_dispatch(*args, **kwargs):
return sync_tasks.sync_signal_direct_dispatch(microsoft_entra_sync_direct, *args, **kwargs)
@actor(description=_("Sync a related object (memberships) for Microsoft Entra provider."))
def microsoft_entra_sync_m2m(*args, **kwargs):
return sync_tasks.sync_signal_m2m(*args, **kwargs)
@actor(
description=_(
"Dispatch syncs for a related object (memberships) for Microsoft Entra providers."
)
)
def microsoft_entra_sync_m2m_dispatch(*args, **kwargs):
return sync_tasks.sync_signal_m2m_dispatch(microsoft_entra_sync_m2m, *args, **kwargs)

View File

@ -252,9 +252,13 @@ class MicrosoftEntraGroupTests(TestCase):
member_add.assert_called_once()
self.assertEqual(
member_add.call_args[0][0].odata_id,
f"https://graph.microsoft.com/v1.0/directoryObjects/{MicrosoftEntraProviderUser.objects.filter(
f"https://graph.microsoft.com/v1.0/directoryObjects/{
MicrosoftEntraProviderUser.objects.filter(
provider=self.provider,
).first().microsoft_id}",
)
.first()
.microsoft_id
}",
)
def test_group_create_member_remove(self):
@ -311,9 +315,13 @@ class MicrosoftEntraGroupTests(TestCase):
member_add.assert_called_once()
self.assertEqual(
member_add.call_args[0][0].odata_id,
f"https://graph.microsoft.com/v1.0/directoryObjects/{MicrosoftEntraProviderUser.objects.filter(
f"https://graph.microsoft.com/v1.0/directoryObjects/{
MicrosoftEntraProviderUser.objects.filter(
provider=self.provider,
).first().microsoft_id}",
)
.first()
.microsoft_id
}",
)
member_remove.assert_called_once()
@ -413,7 +421,7 @@ class MicrosoftEntraGroupTests(TestCase):
),
) as group_list,
):
microsoft_entra_sync.delay(self.provider.pk).get()
microsoft_entra_sync.send(self.provider.pk).get_result()
self.assertTrue(
MicrosoftEntraProviderGroup.objects.filter(
group=different_group, provider=self.provider

View File

@ -397,7 +397,7 @@ class MicrosoftEntraUserTests(APITestCase):
AsyncMock(return_value=GroupCollectionResponse(value=[])),
),
):
microsoft_entra_sync.delay(self.provider.pk).get()
microsoft_entra_sync.send(self.provider.pk).get_result()
self.assertTrue(
MicrosoftEntraProviderUser.objects.filter(
user=different_user, provider=self.provider

View File

@ -17,6 +17,7 @@ from authentik.crypto.models import CertificateKeyPair
from authentik.lib.models import CreatedUpdatedModel
from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
from authentik.tasks.models import TasksModel
class EventTypes(models.TextChoices):
@ -42,7 +43,7 @@ class SSFEventStatus(models.TextChoices):
SENT = "sent"
class SSFProvider(BackchannelProvider):
class SSFProvider(TasksModel, BackchannelProvider):
"""Shared Signals Framework provider to allow applications to
receive user events from authentik."""

View File

@ -1,10 +1,8 @@
from hashlib import sha256
from django.contrib.auth.signals import user_logged_out
from django.db.models import Model
from django.db.models.signals import post_delete, post_save, pre_delete
from django.dispatch import receiver
from django.http.request import HttpRequest
from guardian.shortcuts import assign_perm
from authentik.core.models import (
@ -20,7 +18,7 @@ from authentik.enterprise.providers.ssf.models import (
EventTypes,
SSFProvider,
)
from authentik.enterprise.providers.ssf.tasks import send_ssf_event
from authentik.enterprise.providers.ssf.tasks import send_ssf_events
from authentik.events.middleware import audit_ignore
from authentik.stages.authenticator.models import Device
from authentik.stages.authenticator_duo.models import DuoDevice
@ -62,38 +60,13 @@ def ssf_providers_post_save(sender: type[Model], instance: SSFProvider, created:
instance.save()
@receiver(user_logged_out)
def ssf_user_logged_out_session_revoked(sender, request: HttpRequest, user: User, **_):
"""Session revoked trigger (user logged out)"""
if not request.session or not request.session.session_key or not user:
return
send_ssf_event(
EventTypes.CAEP_SESSION_REVOKED,
{
"initiating_entity": "user",
},
sub_id={
"format": "complex",
"session": {
"format": "opaque",
"id": sha256(request.session.session_key.encode("ascii")).hexdigest(),
},
"user": {
"format": "email",
"email": user.email,
},
},
request=request,
)
@receiver(pre_delete, sender=AuthenticatedSession)
def ssf_user_session_delete_session_revoked(sender, instance: AuthenticatedSession, **_):
"""Session revoked trigger (users' session has been deleted)
As this signal is also triggered with a regular logout, we can't be sure
if the session has been deleted by an admin or by the user themselves."""
send_ssf_event(
send_ssf_events(
EventTypes.CAEP_SESSION_REVOKED,
{
"initiating_entity": "user",
@ -115,7 +88,7 @@ def ssf_user_session_delete_session_revoked(sender, instance: AuthenticatedSessi
@receiver(password_changed)
def ssf_password_changed_cred_change(sender, user: User, password: str | None, **_):
"""Credential change trigger (password changed)"""
send_ssf_event(
send_ssf_events(
EventTypes.CAEP_CREDENTIAL_CHANGE,
{
"credential_type": "password",
@ -153,7 +126,7 @@ def ssf_device_post_save(sender: type[Model], instance: Device, created: bool, *
}
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
data["fido2_aaguid"] = instance.aaguid
send_ssf_event(
send_ssf_events(
EventTypes.CAEP_CREDENTIAL_CHANGE,
data,
sub_id={
@ -180,7 +153,7 @@ def ssf_device_post_delete(sender: type[Model], instance: Device, **_):
}
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
data["fido2_aaguid"] = instance.aaguid
send_ssf_event(
send_ssf_events(
EventTypes.CAEP_CREDENTIAL_CHANGE,
data,
sub_id={

View File

@ -1,7 +1,11 @@
from celery import group
from typing import Any
from uuid import UUID
from django.http import HttpRequest
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_dramatiq_postgres.middleware import CurrentTask
from dramatiq.actor import actor
from requests.exceptions import RequestException
from structlog.stdlib import get_logger
@ -13,19 +17,16 @@ from authentik.enterprise.providers.ssf.models import (
Stream,
StreamEvent,
)
from authentik.events.logs import LogEvent
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask
from authentik.lib.utils.http import get_http_session
from authentik.lib.utils.time import timedelta_from_string
from authentik.policies.engine import PolicyEngine
from authentik.root.celery import CELERY_APP
from authentik.tasks.models import Task
session = get_http_session()
LOGGER = get_logger()
def send_ssf_event(
def send_ssf_events(
event_type: EventTypes,
data: dict,
stream_filter: dict | None = None,
@ -33,7 +34,7 @@ def send_ssf_event(
**extra_data,
):
"""Wrapper to send an SSF event to multiple streams"""
payload = []
events_data = {}
if not stream_filter:
stream_filter = {}
stream_filter["events_requested__contains"] = [event_type]
@ -41,16 +42,22 @@ def send_ssf_event(
extra_data.setdefault("txn", request.request_id)
for stream in Stream.objects.filter(**stream_filter):
event_data = stream.prepare_event_payload(event_type, data, **extra_data)
payload.append((str(stream.uuid), event_data))
return _send_ssf_event.delay(payload)
events_data[stream.uuid] = event_data
ssf_events_dispatch.send(events_data)
def _check_app_access(stream_uuid: str, event_data: dict) -> bool:
@actor(description=_("Dispatch SSF events."))
def ssf_events_dispatch(events_data: dict[str, dict[str, Any]]):
for stream_uuid, event_data in events_data.items():
stream = Stream.objects.filter(pk=stream_uuid).first()
if not stream:
continue
send_ssf_event.send_with_options(args=(stream_uuid, event_data), rel_obj=stream.provider)
def _check_app_access(stream: Stream, event_data: dict) -> bool:
"""Check if event is related to user and if so, check
if the user has access to the application"""
stream = Stream.objects.filter(pk=stream_uuid).first()
if not stream:
return False
# `event_data` is a dict version of a StreamEvent
sub_id = event_data.get("payload", {}).get("sub_id", {})
email = sub_id.get("user", {}).get("email", None)
@ -65,42 +72,22 @@ def _check_app_access(stream_uuid: str, event_data: dict) -> bool:
return engine.passing
@CELERY_APP.task()
def _send_ssf_event(event_data: list[tuple[str, dict]]):
tasks = []
for stream, data in event_data:
if not _check_app_access(stream, data):
continue
event = StreamEvent.objects.create(**data)
tasks.extend(send_single_ssf_event(stream, str(event.uuid)))
main_task = group(*tasks)
main_task()
@actor(description=_("Send an SSF event."))
def send_ssf_event(stream_uuid: UUID, event_data: dict[str, Any]):
self: Task = CurrentTask.get_task()
def send_single_ssf_event(stream_id: str, evt_id: str):
stream = Stream.objects.filter(pk=stream_id).first()
stream = Stream.objects.filter(pk=stream_uuid).first()
if not stream:
return
event = StreamEvent.objects.filter(pk=evt_id).first()
if not event:
if not _check_app_access(stream, event_data):
return
event = StreamEvent.objects.create(**event_data)
self.set_uid(event.pk)
if event.status == SSFEventStatus.SENT:
return
if stream.delivery_method == DeliveryMethods.RISC_PUSH:
return [ssf_push_event.si(str(event.pk))]
return []
@CELERY_APP.task(bind=True, base=SystemTask)
def ssf_push_event(self: SystemTask, event_id: str):
self.save_on_success = False
event = StreamEvent.objects.filter(pk=event_id).first()
if not event:
return
self.set_uid(event_id)
if event.status == SSFEventStatus.SENT:
self.set_status(TaskStatus.SUCCESSFUL)
if stream.delivery_method != DeliveryMethods.RISC_PUSH:
return
try:
response = session.post(
event.stream.endpoint_url,
@ -110,26 +97,17 @@ def ssf_push_event(self: SystemTask, event_id: str):
response.raise_for_status()
event.status = SSFEventStatus.SENT
event.save()
self.set_status(TaskStatus.SUCCESSFUL)
return
except RequestException as exc:
LOGGER.warning("Failed to send SSF event", exc=exc)
self.set_status(TaskStatus.ERROR)
attrs = {}
if exc.response:
attrs["response"] = {
"content": exc.response.text,
"status": exc.response.status_code,
}
self.set_error(
exc,
LogEvent(
_("Failed to send request"),
log_level="warning",
logger=self.__name__,
attributes=attrs,
),
)
self.warning(exc)
self.warning("Failed to send request", **attrs)
# Re-up the expiry of the stream event
event.expires = now() + timedelta_from_string(event.stream.provider.event_retention)
event.status = SSFEventStatus.PENDING_FAILED

View File

@ -13,7 +13,7 @@ from authentik.enterprise.providers.ssf.models import (
SSFProvider,
Stream,
)
from authentik.enterprise.providers.ssf.tasks import send_ssf_event
from authentik.enterprise.providers.ssf.tasks import send_ssf_events
from authentik.enterprise.providers.ssf.views.base import SSFView
LOGGER = get_logger()
@ -109,7 +109,7 @@ class StreamView(SSFView):
"User does not have permission to create stream for this provider."
)
instance: Stream = stream.save(provider=self.provider)
send_ssf_event(
send_ssf_events(
EventTypes.SET_VERIFICATION,
{
"state": None,

View File

View File

@ -0,0 +1,12 @@
"""Enterprise app config"""
from authentik.enterprise.apps import EnterpriseConfig
class AuthentikEnterpriseSearchConfig(EnterpriseConfig):
"""Enterprise app config"""
name = "authentik.enterprise.search"
label = "authentik_search"
verbose_name = "authentik Enterprise.Search"
default = True

View File

@ -0,0 +1,128 @@
"""DjangoQL search"""
from collections import OrderedDict, defaultdict
from collections.abc import Generator
from django.db import connection
from django.db.models import Model, Q
from djangoql.compat import text_type
from djangoql.schema import StrField
class JSONSearchField(StrField):
"""JSON field for DjangoQL"""
model: Model
def __init__(self, model=None, name=None, nullable=None, suggest_nested=True):
# Set this in the constructor to not clobber the type variable
self.type = "relation"
self.suggest_nested = suggest_nested
super().__init__(model, name, nullable)
def get_lookup(self, path, operator, value):
search = "__".join(path)
op, invert = self.get_operator(operator)
q = Q(**{f"{search}{op}": self.get_lookup_value(value)})
return ~q if invert else q
def json_field_keys(self) -> Generator[tuple[str]]:
with connection.cursor() as cursor:
cursor.execute(
f"""
WITH RECURSIVE "{self.name}_keys" AS (
SELECT
ARRAY[jsonb_object_keys("{self.name}")] AS key_path_array,
"{self.name}" -> jsonb_object_keys("{self.name}") AS value
FROM {self.model._meta.db_table}
WHERE "{self.name}" IS NOT NULL
AND jsonb_typeof("{self.name}") = 'object'
UNION ALL
SELECT
ck.key_path_array || jsonb_object_keys(ck.value),
ck.value -> jsonb_object_keys(ck.value) AS value
FROM "{self.name}_keys" ck
WHERE jsonb_typeof(ck.value) = 'object'
),
unique_paths AS (
SELECT DISTINCT key_path_array
FROM "{self.name}_keys"
)
SELECT key_path_array FROM unique_paths;
""" # nosec
)
return (x[0] for x in cursor.fetchall())
def get_nested_options(self) -> OrderedDict:
"""Get keys of all nested objects to show autocomplete"""
if not self.suggest_nested:
return OrderedDict()
base_model_name = f"{self.model._meta.app_label}.{self.model._meta.model_name}_{self.name}"
def recursive_function(parts: list[str], parent_parts: list[str] | None = None):
if not parent_parts:
parent_parts = []
path = parts.pop(0)
parent_parts.append(path)
relation_key = "_".join(parent_parts)
if len(parts) > 1:
out_dict = {
relation_key: {
parts[0]: {
"type": "relation",
"relation": f"{relation_key}_{parts[0]}",
}
}
}
child_paths = recursive_function(parts.copy(), parent_parts.copy())
child_paths.update(out_dict)
return child_paths
else:
return {relation_key: {parts[0]: {}}}
relation_structure = defaultdict(dict)
for relations in self.json_field_keys():
result = recursive_function([base_model_name] + relations)
for relation_key, value in result.items():
for sub_relation_key, sub_value in value.items():
if not relation_structure[relation_key].get(sub_relation_key, None):
relation_structure[relation_key][sub_relation_key] = sub_value
else:
relation_structure[relation_key][sub_relation_key].update(sub_value)
final_dict = defaultdict(dict)
for key, value in relation_structure.items():
for sub_key, sub_value in value.items():
if not sub_value:
final_dict[key][sub_key] = {
"type": "str",
"nullable": True,
}
else:
final_dict[key][sub_key] = sub_value
return OrderedDict(final_dict)
def relation(self) -> str:
return f"{self.model._meta.app_label}.{self.model._meta.model_name}_{self.name}"
class ChoiceSearchField(StrField):
def __init__(self, model=None, name=None, nullable=None):
super().__init__(model, name, nullable, suggest_options=True)
def get_options(self, search):
result = []
choices = self._field_choices()
if choices:
search = search.lower()
for c in choices:
choice = text_type(c[0])
if search in choice.lower():
result.append(choice)
return result

View File

@ -0,0 +1,53 @@
from rest_framework.response import Response
from authentik.api.pagination import Pagination
from authentik.enterprise.search.ql import AUTOCOMPLETE_COMPONENT_NAME, QLSearch
class AutocompletePagination(Pagination):
def paginate_queryset(self, queryset, request, view=None):
self.view = view
return super().paginate_queryset(queryset, request, view)
def get_autocomplete(self):
schema = QLSearch().get_schema(self.request, self.view)
introspections = {}
if hasattr(self.view, "get_ql_fields"):
from authentik.enterprise.search.schema import AKQLSchemaSerializer
introspections = AKQLSchemaSerializer().serialize(
schema(self.page.paginator.object_list.model)
)
return introspections
def get_paginated_response(self, data):
previous_page_number = 0
if self.page.has_previous():
previous_page_number = self.page.previous_page_number()
next_page_number = 0
if self.page.has_next():
next_page_number = self.page.next_page_number()
return Response(
{
"pagination": {
"next": next_page_number,
"previous": previous_page_number,
"count": self.page.paginator.count,
"current": self.page.number,
"total_pages": self.page.paginator.num_pages,
"start_index": self.page.start_index(),
"end_index": self.page.end_index(),
},
"results": data,
"autocomplete": self.get_autocomplete(),
}
)
def get_paginated_response_schema(self, schema):
final_schema = super().get_paginated_response_schema(schema)
final_schema["properties"]["autocomplete"] = {
"$ref": f"#/components/schemas/{AUTOCOMPLETE_COMPONENT_NAME}"
}
final_schema["required"].append("autocomplete")
return final_schema

View File

@ -0,0 +1,80 @@
"""DjangoQL search"""
from django.apps import apps
from django.db.models import QuerySet
from djangoql.ast import Name
from djangoql.exceptions import DjangoQLError
from djangoql.queryset import apply_search
from djangoql.schema import DjangoQLSchema
from rest_framework.filters import BaseFilterBackend, SearchFilter
from rest_framework.request import Request
from structlog.stdlib import get_logger
from authentik.enterprise.search.fields import JSONSearchField
LOGGER = get_logger()
AUTOCOMPLETE_COMPONENT_NAME = "Autocomplete"
AUTOCOMPLETE_SCHEMA = {
"type": "object",
"additionalProperties": {},
}
class BaseSchema(DjangoQLSchema):
"""Base Schema which deals with JSON Fields"""
def resolve_name(self, name: Name):
model = self.model_label(self.current_model)
root_field = name.parts[0]
field = self.models[model].get(root_field)
# If the query goes into a JSON field, return the root
# field as the JSON field will do the rest
if isinstance(field, JSONSearchField):
# This is a workaround; build_filter will remove the right-most
# entry in the path as that is intended to be the same as the field
# however for JSON that is not the case
if name.parts[-1] != root_field:
name.parts.append(root_field)
return field
return super().resolve_name(name)
class QLSearch(BaseFilterBackend):
"""rest_framework search filter which uses DjangoQL"""
def __init__(self):
super().__init__()
self._fallback = SearchFilter()
@property
def enabled(self):
return apps.get_app_config("authentik_enterprise").enabled()
def get_search_terms(self, request: Request) -> str:
"""Search terms are set by a ?search=... query parameter,
and may be comma and/or whitespace delimited."""
params = request.query_params.get("search", "")
params = params.replace("\x00", "") # strip null characters
return params
def get_schema(self, request: Request, view) -> BaseSchema:
ql_fields = []
if hasattr(view, "get_ql_fields"):
ql_fields = view.get_ql_fields()
class InlineSchema(BaseSchema):
def get_fields(self, model):
return ql_fields or []
return InlineSchema
def filter_queryset(self, request: Request, queryset: QuerySet, view) -> QuerySet:
search_query = self.get_search_terms(request)
schema = self.get_schema(request, view)
if len(search_query) == 0 or not self.enabled:
return self._fallback.filter_queryset(request, queryset, view)
try:
return apply_search(queryset, search_query, schema=schema)
except DjangoQLError as exc:
LOGGER.debug("Failed to parse search expression", exc=exc)
return self._fallback.filter_queryset(request, queryset, view)

View File

@ -0,0 +1,29 @@
from djangoql.serializers import DjangoQLSchemaSerializer
from drf_spectacular.generators import SchemaGenerator
from authentik.api.schema import create_component
from authentik.enterprise.search.fields import JSONSearchField
from authentik.enterprise.search.ql import AUTOCOMPLETE_COMPONENT_NAME, AUTOCOMPLETE_SCHEMA
class AKQLSchemaSerializer(DjangoQLSchemaSerializer):
def serialize(self, schema):
serialization = super().serialize(schema)
for _, fields in schema.models.items():
for _, field in fields.items():
if not isinstance(field, JSONSearchField):
continue
serialization["models"].update(field.get_nested_options())
return serialization
def serialize_field(self, field):
result = super().serialize_field(field)
if isinstance(field, JSONSearchField):
result["relation"] = field.relation()
return result
def postprocess_schema_search_autocomplete(result, generator: SchemaGenerator, **kwargs):
create_component(generator, AUTOCOMPLETE_COMPONENT_NAME, AUTOCOMPLETE_SCHEMA)
return result

View File

@ -0,0 +1,17 @@
SPECTACULAR_SETTINGS = {
"POSTPROCESSING_HOOKS": [
"authentik.api.schema.postprocess_schema_responses",
"authentik.enterprise.search.schema.postprocess_schema_search_autocomplete",
"drf_spectacular.hooks.postprocess_schema_enums",
],
}
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "authentik.enterprise.search.pagination.AutocompletePagination",
"DEFAULT_FILTER_BACKENDS": [
"authentik.enterprise.search.ql.QLSearch",
"authentik.rbac.filters.ObjectFilter",
"django_filters.rest_framework.DjangoFilterBackend",
"rest_framework.filters.OrderingFilter",
],
}

View File

@ -0,0 +1,78 @@
from json import loads
from unittest.mock import PropertyMock, patch
from urllib.parse import urlencode
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user
@patch(
"authentik.enterprise.audit.middleware.EnterpriseAuditMiddleware.enabled",
PropertyMock(return_value=True),
)
class QLTest(APITestCase):
def setUp(self):
self.user = create_test_admin_user()
# ensure we have more than 1 user
create_test_admin_user()
def test_search(self):
"""Test simple search query"""
self.client.force_login(self.user)
query = f'username = "{self.user.username}"'
res = self.client.get(
reverse(
"authentik_api:user-list",
)
+ f"?{urlencode({"search": query})}"
)
self.assertEqual(res.status_code, 200)
content = loads(res.content)
self.assertEqual(content["pagination"]["count"], 1)
self.assertEqual(content["results"][0]["username"], self.user.username)
def test_no_search(self):
"""Ensure works with no search query"""
self.client.force_login(self.user)
res = self.client.get(
reverse(
"authentik_api:user-list",
)
)
self.assertEqual(res.status_code, 200)
content = loads(res.content)
self.assertNotEqual(content["pagination"]["count"], 1)
def test_search_no_ql(self):
"""Test simple search query (no QL)"""
self.client.force_login(self.user)
res = self.client.get(
reverse(
"authentik_api:user-list",
)
+ f"?{urlencode({"search": self.user.username})}"
)
self.assertEqual(res.status_code, 200)
content = loads(res.content)
self.assertEqual(content["pagination"]["count"], 1)
self.assertEqual(content["results"][0]["username"], self.user.username)
def test_search_json(self):
"""Test search query with a JSON attribute"""
self.user.attributes = {"foo": {"bar": "baz"}}
self.user.save()
self.client.force_login(self.user)
query = 'attributes.foo.bar = "baz"'
res = self.client.get(
reverse(
"authentik_api:user-list",
)
+ f"?{urlencode({"search": query})}"
)
self.assertEqual(res.status_code, 200)
content = loads(res.content)
self.assertEqual(content["pagination"]["count"], 1)
self.assertEqual(content["results"][0]["username"], self.user.username)

View File

@ -1,23 +1,12 @@
"""Enterprise additional settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"enterprise_update_usage": {
"task": "authentik.enterprise.tasks.enterprise_update_usage",
"schedule": crontab(minute=fqdn_rand("enterprise_update_usage"), hour="*/2"),
"options": {"queue": "authentik_scheduled"},
}
}
TENANT_APPS = [
"authentik.enterprise.audit",
"authentik.enterprise.policies.unique_password",
"authentik.enterprise.providers.google_workspace",
"authentik.enterprise.providers.microsoft_entra",
"authentik.enterprise.providers.ssf",
"authentik.enterprise.search",
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
"authentik.enterprise.stages.mtls",
"authentik.enterprise.stages.source",

View File

@ -10,6 +10,7 @@ from django.utils.timezone import get_current_timezone
from authentik.enterprise.license import CACHE_KEY_ENTERPRISE_LICENSE
from authentik.enterprise.models import License
from authentik.enterprise.tasks import enterprise_update_usage
from authentik.tasks.schedules.models import Schedule
@receiver(pre_save, sender=License)
@ -26,7 +27,7 @@ def pre_save_license(sender: type[License], instance: License, **_):
def post_save_license(sender: type[License], instance: License, **_):
"""Trigger license usage calculation when license is saved"""
cache.delete(CACHE_KEY_ENTERPRISE_LICENSE)
enterprise_update_usage.delay()
Schedule.dispatch_by_actor(enterprise_update_usage)
@receiver(post_delete, sender=License)

View File

@ -97,6 +97,7 @@ class SourceStageFinal(StageView):
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
self.logger.info("Replacing source flow with overridden flow", flow=token.flow.slug)
plan = token.plan
plan.context.update(self.executor.plan.context)
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
response = plan.to_redirect(self.request, token.flow)
token.delete()

View File

@ -90,14 +90,17 @@ class TestSourceStage(FlowTestCase):
plan: FlowPlan = session[SESSION_KEY_PLAN]
plan.insert_stage(in_memory_stage(SourceStageFinal), index=0)
plan.context[PLAN_CONTEXT_IS_RESTORED] = flow_token
plan.context["foo"] = "bar"
session[SESSION_KEY_PLAN] = plan
session.save()
# Pretend we've just returned from the source
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), follow=True
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(
response, reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug})
)
with self.assertFlowFinishes() as ff:
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), follow=True
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(
response, reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug})
)
self.assertEqual(ff().context["foo"], "bar")

View File

@ -1,14 +1,11 @@
"""Enterprise tasks"""
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import actor
from authentik.enterprise.license import LicenseKey
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask, prefill_task
from authentik.root.celery import CELERY_APP
@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def enterprise_update_usage(self: SystemTask):
"""Update enterprise license status"""
@actor(description=_("Update enterprise license status."))
def enterprise_update_usage():
LicenseKey.get_total().record_usage()
self.set_status(TaskStatus.SUCCESSFUL)

View File

@ -132,6 +132,22 @@ class EventViewSet(ModelViewSet):
]
filterset_class = EventsFilter
def get_ql_fields(self):
from djangoql.schema import DateTimeField, StrField
from authentik.enterprise.search.fields import ChoiceSearchField, JSONSearchField
return [
ChoiceSearchField(Event, "action"),
StrField(Event, "event_uuid"),
StrField(Event, "app", suggest_options=True),
StrField(Event, "client_ip"),
JSONSearchField(Event, "user", suggest_nested=False),
JSONSearchField(Event, "brand", suggest_nested=False),
JSONSearchField(Event, "context", suggest_nested=False),
DateTimeField(Event, "created", suggest_options=True),
]
@extend_schema(
methods=["GET"],
responses={200: EventTopPerUserSerializer(many=True)},

View File

@ -11,7 +11,7 @@ from authentik.events.models import NotificationRule
class NotificationRuleSerializer(ModelSerializer):
"""NotificationRule Serializer"""
group_obj = GroupSerializer(read_only=True, source="group")
destination_group_obj = GroupSerializer(read_only=True, source="destination_group")
class Meta:
model = NotificationRule
@ -20,8 +20,9 @@ class NotificationRuleSerializer(ModelSerializer):
"name",
"transports",
"severity",
"group",
"group_obj",
"destination_group",
"destination_group_obj",
"destination_event_user",
]
@ -30,6 +31,6 @@ class NotificationRuleViewSet(UsedByMixin, ModelViewSet):
queryset = NotificationRule.objects.all()
serializer_class = NotificationRuleSerializer
filterset_fields = ["name", "severity", "group__name"]
filterset_fields = ["name", "severity", "destination_group__name"]
ordering = ["name"]
search_fields = ["name", "group__name"]
search_fields = ["name", "destination_group__name"]

View File

@ -1,104 +0,0 @@
"""Tasks API"""
from importlib import import_module
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action
from rest_framework.fields import (
CharField,
ChoiceField,
DateTimeField,
FloatField,
SerializerMethodField,
)
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet
from structlog.stdlib import get_logger
from authentik.core.api.utils import ModelSerializer
from authentik.events.logs import LogEventSerializer
from authentik.events.models import SystemTask, TaskStatus
from authentik.rbac.decorators import permission_required
LOGGER = get_logger()
class SystemTaskSerializer(ModelSerializer):
"""Serialize TaskInfo and TaskResult"""
name = CharField()
full_name = SerializerMethodField()
uid = CharField(required=False)
description = CharField()
start_timestamp = DateTimeField(read_only=True)
finish_timestamp = DateTimeField(read_only=True)
duration = FloatField(read_only=True)
status = ChoiceField(choices=[(x.value, x.name) for x in TaskStatus])
messages = LogEventSerializer(many=True)
def get_full_name(self, instance: SystemTask) -> str:
"""Get full name with UID"""
if instance.uid:
return f"{instance.name}:{instance.uid}"
return instance.name
class Meta:
model = SystemTask
fields = [
"uuid",
"name",
"full_name",
"uid",
"description",
"start_timestamp",
"finish_timestamp",
"duration",
"status",
"messages",
"expires",
"expiring",
]
class SystemTaskViewSet(ReadOnlyModelViewSet):
"""Read-only view set that returns all background tasks"""
queryset = SystemTask.objects.all()
serializer_class = SystemTaskSerializer
filterset_fields = ["name", "uid", "status"]
ordering = ["name", "uid", "status"]
search_fields = ["name", "description", "uid", "status"]
@permission_required(None, ["authentik_events.run_task"])
@extend_schema(
request=OpenApiTypes.NONE,
responses={
204: OpenApiResponse(description="Task retried successfully"),
404: OpenApiResponse(description="Task not found"),
500: OpenApiResponse(description="Failed to retry task"),
},
)
@action(detail=True, methods=["POST"], permission_classes=[])
def run(self, request: Request, pk=None) -> Response:
"""Run task"""
task: SystemTask = self.get_object()
try:
task_module = import_module(task.task_call_module)
task_func = getattr(task_module, task.task_call_func)
LOGGER.info("Running task", task=task_func)
task_func.delay(*task.task_call_args, **task.task_call_kwargs)
messages.success(
self.request,
_("Successfully started task {name}.".format_map({"name": task.name})),
)
return Response(status=204)
except (ImportError, AttributeError) as exc: # pragma: no cover
LOGGER.warning("Failed to run task, remove state", task=task.name, exc=exc)
# if we get an import error, the module path has probably changed
task.delete()
return Response(status=500)

View File

@ -1,12 +1,11 @@
"""authentik events app"""
from celery.schedules import crontab
from prometheus_client import Gauge, Histogram
from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.config import CONFIG, ENV_PREFIX
from authentik.lib.utils.reflection import path_to_class
from authentik.root.celery import CELERY_APP
from authentik.lib.utils.time import fqdn_rand
from authentik.tasks.schedules.lib import ScheduleSpec
# TODO: Deprecated metric - remove in 2024.2 or later
GAUGE_TASKS = Gauge(
@ -35,6 +34,17 @@ class AuthentikEventsConfig(ManagedAppConfig):
verbose_name = "authentik Events"
default = True
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.events.tasks import notification_cleanup
return [
ScheduleSpec(
actor=notification_cleanup,
crontab=f"{fqdn_rand('notification_cleanup')} */8 * * *",
),
]
@ManagedAppConfig.reconcile_global
def check_deprecations(self):
"""Check for config deprecations"""
@ -56,41 +66,3 @@ class AuthentikEventsConfig(ManagedAppConfig):
replacement_env=replace_env,
message=msg,
).save()
@ManagedAppConfig.reconcile_tenant
def prefill_tasks(self):
"""Prefill tasks"""
from authentik.events.models import SystemTask
from authentik.events.system_tasks import _prefill_tasks
for task in _prefill_tasks:
if SystemTask.objects.filter(name=task.name).exists():
continue
task.save()
self.logger.debug("prefilled task", task_name=task.name)
@ManagedAppConfig.reconcile_tenant
def run_scheduled_tasks(self):
"""Run schedule tasks which are behind schedule (only applies
to tasks of which we keep metrics)"""
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask as CelerySystemTask
for task in CELERY_APP.conf["beat_schedule"].values():
schedule = task["schedule"]
if not isinstance(schedule, crontab):
continue
task_class: CelerySystemTask = path_to_class(task["task"])
if not isinstance(task_class, CelerySystemTask):
continue
db_task = task_class.db()
if not db_task:
continue
due, _ = schedule.is_due(db_task.finish_timestamp)
if due or db_task.status == TaskStatus.UNKNOWN:
self.logger.debug("Running past-due scheduled task", task=task["task"])
task_class.apply_async(
args=task.get("args", None),
kwargs=task.get("kwargs", None),
**task.get("options", {}),
)

View File

@ -15,13 +15,13 @@ class MMDBContextProcessor(EventContextProcessor):
self.reader: Reader | None = None
self._last_mtime: float = 0.0
self.logger = get_logger()
self.open()
self.load()
def path(self) -> str | None:
"""Get the path to the MMDB file to load"""
raise NotImplementedError
def open(self):
def load(self):
"""Get GeoIP Reader, if configured, otherwise none"""
path = self.path()
if path == "" or not path:
@ -44,7 +44,7 @@ class MMDBContextProcessor(EventContextProcessor):
diff = self._last_mtime < mtime
if diff > 0:
self.logger.info("Found new MMDB Database, reopening", diff=diff, path=path)
self.open()
self.load()
except OSError as exc:
self.logger.warning("Failed to check MMDB age", exc=exc)

View File

@ -19,7 +19,7 @@ from authentik.blueprints.v1.importer import excluded_models
from authentik.core.models import Group, User
from authentik.events.models import Event, EventAction, Notification
from authentik.events.utils import model_to_dict
from authentik.lib.sentry import before_send
from authentik.lib.sentry import should_ignore_exception
from authentik.lib.utils.errors import exception_to_string
from authentik.stages.authenticator_static.models import StaticToken
@ -173,7 +173,7 @@ class AuditMiddleware:
message=exception_to_string(exception),
)
thread.run()
elif before_send({}, {"exc_info": (None, exception, None)}) is not None:
elif not should_ignore_exception(exception):
thread = EventNewThread(
EventAction.SYSTEM_EXCEPTION,
request,

View File

@ -0,0 +1,26 @@
# Generated by Django 5.1.11 on 2025-06-16 23:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_events", "0009_remove_notificationtransport_webhook_mapping_and_more"),
]
operations = [
migrations.RenameField(
model_name="notificationrule",
old_name="group",
new_name="destination_group",
),
migrations.AddField(
model_name="notificationrule",
name="destination_event_user",
field=models.BooleanField(
default=False,
help_text="When enabled, notification will be sent to user the user that triggered the event.When destination_group is configured, notification is sent to both.",
),
),
]

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