Compare commits

...

173 Commits

Author SHA1 Message Date
b3883f7fbf add exec button
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:20:55 +01:00
87c6b0128a full height modal
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:08:15 +01:00
b243c97916 policies/expression: add inline expression tester
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:08:15 +01:00
3f66527521 unrelated cleanup
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:08:15 +01:00
2f7c258657 some real ugly code
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:07:20 +01:00
917c90374f base preview in expr policy
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:07:20 +01:00
e9c944c0d5 web/user: fix redirects back to user settings (#13076)
closes #13075

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-16 18:06:59 +01:00
b865e97973 ci: parallelize unit tests (#13036)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-02-16 17:35:38 +01:00
24a364bd6b core, web: update translations (#13072)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-02-16 02:56:08 +01:00
65579c0a2b stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#13073)
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-02-15 22:10:17 +01:00
de20897321 root: Improve debugging experience (#12961)
* set remote debugging path to working directory

* add docker-compose.override.yml to gitignore

* fix missing trailing newline

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-02-15 00:51:28 +01:00
39f7bc8e9b core, web: update translations (#13071)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-02-14 20:02:27 +00:00
4ade549ce2 translate: Updates for file locale/en/LC_MESSAGES/django.po in nl [Manual Sync] (#13070)
Translate django.po in nl [Manual Sync]

72% of minimum 60% translated source file: 'django.po'
on 'nl'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 19:12:44 +00:00
a4d87ef011 translate: Updates for file web/xliff/en.xlf in it [Manual Sync] (#13047)
* Translate web/xliff/en.xlf in it [Manual Sync]

96% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'it'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in it [Manual Sync]

95% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'it'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in it [Manual Sync]

95% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'it'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-02-14 18:33:54 +00:00
b851c3daaf translate: Updates for file web/xliff/en.xlf in de [Manual Sync] (#13048)
* Translate web/xliff/en.xlf in de [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in de [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in de [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in de [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* Translate web/xliff/en.xlf in de [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-02-14 18:30:41 +00:00
198af84b3b translate: Updates for file web/xliff/en.xlf in tr [Manual Sync] (#13049)
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:58:59 +00:00
69ced3ae02 translate: Updates for file web/xliff/en.xlf in ko [Manual Sync] (#13045)
Translate web/xliff/en.xlf in ko [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'ko'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:32:54 +00:00
4a2f58561b translate: Updates for file web/xliff/en.xlf in pl [Manual Sync] (#13043)
Translate web/xliff/en.xlf in pl [Manual Sync]

88% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'pl'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:18:48 +00:00
8becaf3418 translate: Updates for file web/xliff/en.xlf in ru [Manual Sync] (#13055)
Translate web/xliff/en.xlf in ru [Manual Sync]

90% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'ru'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:18:18 +00:00
bcfbc46839 translate: Updates for file locale/en/LC_MESSAGES/django.po in pl [Manual Sync] (#13062)
Translate django.po in pl [Manual Sync]

86% of minimum 60% translated source file: 'django.po'
on 'pl'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:17:43 +00:00
af287ee7b0 translate: Updates for file web/xliff/en.xlf in zh_TW [Manual Sync] (#13056)
Translate web/xliff/en.xlf in zh_TW [Manual Sync]

74% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'zh_TW'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:17:24 +00:00
ebf3d12874 translate: Updates for file locale/en/LC_MESSAGES/django.po in nl [Manual Sync] (#13058)
Translate django.po in nl [Manual Sync]

72% of minimum 60% translated source file: 'django.po'
on 'nl'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:16:51 +00:00
7fbdd0452e translate: Updates for file locale/en/LC_MESSAGES/django.po in ru [Manual Sync] (#13063)
Translate django.po in ru [Manual Sync]

90% of minimum 60% translated source file: 'django.po'
on 'ru'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:16:27 +00:00
18298a856f translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_TW [Manual Sync] (#13064)
Translate django.po in zh_TW [Manual Sync]

83% of minimum 60% translated source file: 'django.po'
on 'zh_TW'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:15:56 +00:00
ef6836207a translate: Updates for file locale/en/LC_MESSAGES/django.po in ko [Manual Sync] (#13060)
Translate django.po in ko [Manual Sync]

71% of minimum 60% translated source file: 'django.po'
on 'ko'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:15:38 +00:00
5ad176adf2 translate: Updates for file web/xliff/en.xlf in nl [Manual Sync] (#13044)
Translate web/xliff/en.xlf in nl [Manual Sync]

69% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'nl'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 17:14:07 +00:00
011afc8b2f web: Silence ESBuild warning. (#13025) 2025-02-14 18:00:26 +01:00
4c32c1503b translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans [Manual Sync] (#13066)
Translate django.po in zh-Hans [Manual Sync]

98% of minimum 60% translated source file: 'django.po'
on 'zh-Hans'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:43:59 +00:00
774a8e6eeb translate: Updates for file locale/en/LC_MESSAGES/django.po in tr [Manual Sync] (#13061)
Translate django.po in tr [Manual Sync]

95% of minimum 60% translated source file: 'django.po'
on 'tr'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:43:27 +00:00
297d7f100a translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN [Manual Sync] (#13065)
Translate django.po in zh_CN [Manual Sync]

98% of minimum 60% translated source file: 'django.po'
on 'zh_CN'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:43:10 +00:00
0d3692a619 translate: Updates for file locale/en/LC_MESSAGES/django.po in it [Manual Sync] (#13057)
Translate django.po in it [Manual Sync]

98% of minimum 60% translated source file: 'django.po'
on 'it'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:42:29 +00:00
ba20748b07 translate: Updates for file locale/en/LC_MESSAGES/django.po in pt_BR [Manual Sync] (#13059)
Translate django.po in pt_BR [Manual Sync]

77% of minimum 60% translated source file: 'django.po'
on 'pt_BR'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:42:00 +00:00
3fc296ad0b translate: Updates for file locale/en/LC_MESSAGES/django.po in de [Manual Sync] (#13051)
Translate django.po in de [Manual Sync]

98% of minimum 60% translated source file: 'django.po'
on 'de'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:40:54 +00:00
0aba428787 translate: Updates for file locale/en/LC_MESSAGES/django.po in fi [Manual Sync] (#13052)
Translate django.po in fi [Manual Sync]

98% of minimum 60% translated source file: 'django.po'
on 'fi'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:40:39 +00:00
4a88e29de6 translate: Updates for file web/xliff/en.xlf in zh-Hans [Manual Sync] (#13050)
Translate en.xlf in zh-Hans [Manual Sync]

98% of minimum 60% translated source file: 'en.xlf'
on 'zh-Hans'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:40:17 +00:00
0d6fced7d8 translate: Updates for file locale/en/LC_MESSAGES/django.po in es [Manual Sync] (#13054)
Translate django.po in es [Manual Sync]

97% of minimum 60% translated source file: 'django.po'
on 'es'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:39:49 +00:00
29c6c1e33b translate: Updates for file web/xliff/en.xlf in zh_CN [Manual Sync] (#13053)
Translate web/xliff/en.xlf in zh_CN [Manual Sync]

98% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'zh_CN'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:39:33 +00:00
e2e8b7c114 translate: Updates for file web/xliff/en.xlf in fi [Manual Sync] (#13046)
Translate web/xliff/en.xlf in fi [Manual Sync]

98% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'fi'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:35:39 +00:00
bf2e854f12 translate: Updates for file web/xliff/en.xlf in es [Manual Sync] (#13042)
Translate web/xliff/en.xlf in es [Manual Sync]

78% of minimum 60% translated source file: 'web/xliff/en.xlf'
on 'es'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:35:06 +00:00
3fbc059f2d translate: Updates for file web/xliff/en.xlf in fr (#13041)
Translate web/xliff/en.xlf in fr

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:30:51 +00:00
e051e8ebd8 translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#13040)
Translate locale/en/LC_MESSAGES/django.po in fr

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 16:25:14 +00:00
880a99efe5 website: bump prettier from 3.5.0 to 3.5.1 in /website (#13028)
Bumps [prettier](https://github.com/prettier/prettier) from 3.5.0 to 3.5.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.5.0...3.5.1)

---
updated-dependencies:
- dependency-name: prettier
  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-02-14 17:01:10 +01:00
27d5063d16 core: bump google-api-python-client from 2.160.0 to 2.161.0 (#13029)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.160.0 to 2.161.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.160.0...v2.161.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  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-02-14 17:01:01 +01:00
e130bca344 core: bump msgraph-sdk from 1.20.0 to 1.21.0 (#13030)
Bumps [msgraph-sdk](https://github.com/microsoftgraph/msgraph-sdk-python) from 1.20.0 to 1.21.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.20.0...v1.21.0)

---
updated-dependencies:
- dependency-name: msgraph-sdk
  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-02-14 17:00:52 +01:00
325d590679 core: bump goauthentik.io/api/v3 from 3.2024123.3 to 3.2024123.4 (#13031)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024123.3 to 3.2024123.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.2024123.3...v3.2024123.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-14 17:00:38 +01:00
f40a4b5076 core, web: update translations (#13039)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-02-14 15:14:03 +00:00
89a19f6e4c translate: Updates for file locale/en/LC_MESSAGES/django.po in pl (#13037) 2025-02-14 14:33:04 +00:00
9bc51c683e translate: Updates for file locale/en/LC_MESSAGES/django.po in fi (#13034)
Translate locale/en/LC_MESSAGES/django.po in fi

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-14 13:50:03 +00:00
3d2bd4d8dd web: Fix issues surrounding wizard step behavior. (#12779)
This resolves a few stateful situations which may arise when opening and
closing wizard pages.
2025-02-14 02:12:46 +01:00
46a968d1dd web: Improve form input validation and visibility. (#12812) 2025-02-14 02:11:35 +01:00
49cc70eb96 web: Enhance accordion header interactions for better UX (#12813)
web: Refine accordion headers for pressability.

- Allows user to click or tap anywhere on a accordion header to expand
  or collapse.
- Adds transition to collapse.
2025-02-14 02:10:31 +01:00
143b02b51a core: revert bump oss/go/microsoft/golang from 1.23-fips-bookworm to 1.24-fips-bookworm (#13012) (#13022) 2025-02-13 18:42:13 +01:00
5904fae80b root: correctly use correct schema for install_id (#13018)
* root: correctly use correct schema for install_id

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

#13006

* format

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-13 16:45:06 +01:00
6f9479a085 website: bump docusaurus-plugin-openapi-docs from 4.3.3 to 4.3.4 in /website (#13011)
website: bump docusaurus-plugin-openapi-docs in /website

Bumps [docusaurus-plugin-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-plugin-openapi-docs) from 4.3.3 to 4.3.4.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.4/packages/docusaurus-plugin-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-plugin-openapi-docs
  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-02-13 14:27:24 +01:00
ce10dbfa4e web: bump API Client version (#13017)
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-02-13 12:59:30 +00:00
394881dcd3 core: bump aws-cdk-lib from 2.178.1 to 2.178.2 (#13013)
Bumps [aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.178.1 to 2.178.2.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/compare/v2.178.1...v2.178.2)

---
updated-dependencies:
- dependency-name: aws-cdk-lib
  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-02-13 13:47:23 +01:00
a6e322507c core: bump oss/go/microsoft/golang from 1.23-fips-bookworm to 1.24-fips-bookworm (#13012)
core: bump oss/go/microsoft/golang

Bumps oss/go/microsoft/golang from 1.23-fips-bookworm to 1.24-fips-bookworm.

---
updated-dependencies:
- dependency-name: oss/go/microsoft/golang
  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-02-13 13:43:55 +01:00
755e2f1507 website: bump docusaurus-theme-openapi-docs from 4.3.3 to 4.3.4 in /website (#13010)
website: bump docusaurus-theme-openapi-docs in /website

Bumps [docusaurus-theme-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-theme-openapi-docs) from 4.3.3 to 4.3.4.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.4/packages/docusaurus-theme-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-theme-openapi-docs
  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-02-13 13:43:45 +01:00
d41c9eb442 lifecycle/aws: bump aws-cdk from 2.178.1 to 2.178.2 in /lifecycle/aws (#13009)
Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.178.1 to 2.178.2.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.178.2/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  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-02-13 13:43:39 +01:00
dea48e6ac7 core: bump github.com/sethvargo/go-envconfig from 1.1.0 to 1.1.1 (#13008)
Bumps [github.com/sethvargo/go-envconfig](https://github.com/sethvargo/go-envconfig) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/sethvargo/go-envconfig/releases)
- [Commits](https://github.com/sethvargo/go-envconfig/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: github.com/sethvargo/go-envconfig
  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-02-13 13:43:30 +01:00
1614f3174f web/admin: fix source selection for identification stage (#13007)
closes #12995

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-13 13:30:04 +01:00
d18950f7bb core: bump sentry-sdk from 2.20.0 to 2.21.0 (#13014)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.20.0 to 2.21.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.20.0...2.21.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 13:29:30 +01:00
4fe533a92f website/integrations: Open WebUI (#12939)
* initial release

* Ready for PR

* index.md aktualisieren

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Add stuff for dominic-r :)

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* index.md aktualisieren

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* index.md aktualisieren

* make website...

* make website...

* changes from comments

* changes from comments

---------

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>
Co-authored-by: nicedevil007 <nicedevil007@users.noreply.github.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-02-13 04:56:40 -06:00
82d4e8aa4e root: use correct default schema for install_id (#13006)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-13 01:25:13 +01:00
98129d3e9a website/docs: fix a minor typo (#13004) 2025-02-12 23:48:50 +00:00
98f3b9ae97 enterprise/providers/ssf: fixes v2 (#13003)
* enterprise/providers/ssf: check providers's application's policies to determine if an ssf event should be sent

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

* add preview banner to ssf provider

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

* fix and test

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-13 00:23:52 +01:00
bd69dbc0e1 root: make default postgres schema configurable (#12949)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-12 23:57:47 +01:00
ac4d6ae9f6 providers/oauth2: cleanup tokens when user is deactivated (#12859)
* providers/oauth2: cleanup tokens when user is deactivated

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* use signal

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* use post_save signal

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

* delete access tokens too

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

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-02-12 15:13:37 +00:00
cdc0d0a857 website/docs: fix Nginx redirection example (#12920)
Fix Nginx redirection
2025-02-12 14:11:01 +01:00
3656c38aa0 core: bump twilio from 9.4.4 to 9.4.5 (#12993)
Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.4 to 9.4.5.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/9.4.4...9.4.5)

---
updated-dependencies:
- dependency-name: twilio
  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-02-12 14:09:49 +01:00
fe4e364492 core: bump coverage from 7.6.11 to 7.6.12 (#12994)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.11 to 7.6.12.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.6.11...7.6.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 14:09:39 +01:00
ce86cbe2a0 core: bump cryptography from 44.0.0 to 44.0.1 (#12992)
Bumps [cryptography](https://github.com/pyca/cryptography) from 44.0.0 to 44.0.1.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/44.0.0...44.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  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-02-12 00:39:00 +01:00
8f0e9ff534 web/admin: improve user display view (#12988)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-11 17:53:03 +01:00
ff60607851 enterprise/providers/SSF: fix a couple of bugs after real world testing (#12987)
* providers/ssf: fix txn being inside the event not the SET itself

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

* fix incorrect ssf format

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

* fix web form

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-11 15:08:06 +01:00
b6cf27b421 website: bump serialize-javascript from 6.0.1 to 6.0.2 in /website (#12986)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-11 14:45:51 +01:00
9457c80d62 web: bump esbuild from 0.24.0 to 0.25.0 in /web (#12978)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2024.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-11 13:56:13 +01:00
409035b692 core: bump ruff from 0.9.5 to 0.9.6 (#12980)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.5 to 0.9.6.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.9.5...0.9.6)

---
updated-dependencies:
- dependency-name: ruff
  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-02-11 13:56:00 +01:00
7798d16e01 core: bump pytest-django from 4.9.0 to 4.10.0 (#12981)
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.9.0 to 4.10.0.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.9.0...v4.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-11 13:55:45 +01:00
8f16a182aa website: bump postcss from 8.5.1 to 8.5.2 in /website (#12983)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.1 to 8.5.2.
- [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.1...8.5.2)

---
updated-dependencies:
- dependency-name: postcss
  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-02-11 13:55:29 +01:00
50c68df0a1 core: bump lxml from 5.3.0 to 5.3.1 (#12982)
Bumps [lxml](https://github.com/lxml/lxml) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-5.3.0...lxml-5.3.1)

---
updated-dependencies:
- dependency-name: lxml
  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-02-11 13:55:22 +01:00
556248c7c9 core: bump goauthentik.io/api/v3 from 3.2024123.2 to 3.2024123.3 (#12984)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024123.2 to 3.2024123.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.2024123.2...v3.2024123.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-11 13:55:01 +01:00
ed2e2380cc web: bump API Client version (#12974)
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-02-10 19:00:43 +01:00
1f79b5acb7 core: show last password change date (#12958)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-10 16:13:04 +01:00
6185e7cdc7 website: bump wireit from 0.14.9 to 0.14.11 in /website (#12971)
Bumps [wireit](https://github.com/google/wireit) from 0.14.9 to 0.14.11.
- [Changelog](https://github.com/google/wireit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/wireit/compare/v0.14.9...v0.14.11)

---
updated-dependencies:
- dependency-name: wireit
  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-02-10 15:33:28 +01:00
aedce2a6a1 website: bump prettier from 3.4.2 to 3.5.0 in /website (#12970)
Bumps [prettier](https://github.com/prettier/prettier) from 3.4.2 to 3.5.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.4.2...3.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 15:33:03 +01:00
fefa189ff4 core: bump coverage from 7.6.10 to 7.6.11 (#12972)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.10 to 7.6.11.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.6.10...7.6.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 15:32:34 +01:00
b5bdad6804 core: bump aws-cdk-lib from 2.178.0 to 2.178.1 (#12952)
Bumps [aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.178.0 to 2.178.1.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/v2.178.1/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/compare/v2.178.0...v2.178.1)

---
updated-dependencies:
- dependency-name: aws-cdk-lib
  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-02-10 01:46:06 +01:00
1d03f92dee core: bump ruff from 0.9.4 to 0.9.5 (#12953)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.4 to 0.9.5.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.9.4...0.9.5)

---
updated-dependencies:
- dependency-name: ruff
  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-02-10 01:45:55 +01:00
01b20153ca core: bump msgraph-sdk from 1.18.0 to 1.20.0 (#12954)
Bumps [msgraph-sdk](https://github.com/microsoftgraph/msgraph-sdk-python) from 1.18.0 to 1.20.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.18.0...v1.20.0)

---
updated-dependencies:
- dependency-name: msgraph-sdk
  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-02-10 01:45:44 +01:00
83a2728500 lifecycle/aws: bump aws-cdk from 2.178.0 to 2.178.1 in /lifecycle/aws (#12955)
Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.178.0 to 2.178.1.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/v2.178.1/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.178.1/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  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-02-10 01:45:34 +01:00
c57f17bff8 ci: bump docker/setup-qemu-action from 3.3.0 to 3.4.0 (#12956)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  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-02-10 01:45:24 +01:00
5533f7dd7a translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#12964)
Translate locale/en/LC_MESSAGES/django.po in de

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-08 19:55:39 +00:00
daebeb1192 *: remove outdated preview badges (#12950)
* remove outdated preview badges

* remove from web ui too

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-02-07 00:02:17 +01:00
26a08fcaac core: bump aws-cdk-lib from 2.177.0 to 2.178.0 (#12944)
Bumps [aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.177.0 to 2.178.0.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/compare/v2.177.0...v2.178.0)

---
updated-dependencies:
- dependency-name: aws-cdk-lib
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 10:08:45 +01:00
330fc8cee3 core: bump django from 5.0.11 to 5.0.12 (#12945)
Bumps [django](https://github.com/django/django) from 5.0.11 to 5.0.12.
- [Commits](https://github.com/django/django/compare/5.0.11...5.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 10:08:24 +01:00
205c01038f core: bump dacite from 1.9.1 to 1.9.2 (#12946)
Bumps [dacite](https://github.com/konradhalas/dacite) from 1.9.1 to 1.9.2.
- [Release notes](https://github.com/konradhalas/dacite/releases)
- [Changelog](https://github.com/konradhalas/dacite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/konradhalas/dacite/compare/v1.9.1...v1.9.2)

---
updated-dependencies:
- dependency-name: dacite
  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-02-06 10:08:16 +01:00
23eb93c981 core: bump goauthentik.io/api/v3 from 3.2024123.1 to 3.2024123.2 (#12947)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024123.1 to 3.2024123.2.
- [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.2024123.1...v3.2024123.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 10:08:07 +01:00
5679352c15 lifecycle/aws: bump aws-cdk from 2.177.0 to 2.178.0 in /lifecycle/aws (#12948)
Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.177.0 to 2.178.0.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.178.0/packages/aws-cdk)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 10:07:59 +01:00
fb7d637da1 web: bump API Client version (#12941)
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-02-05 17:55:35 +01:00
cee48909e9 translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#12937)
Translate locale/en/LC_MESSAGES/django.po in de

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-02-05 17:55:17 +01:00
6549b303d5 enterprise/providers: SSF (#12327)
* init

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

* fix some other stuff

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

* more progress

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

* fix missing format

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

* make it work, send verification event

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

* progress

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

* more progress

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

* fix

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

* save iss

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

* add signals for MFA devices

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

* fix tests

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

* refactor more

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

* re-work auth

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

* add API to list ssf streams

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

* start rbac

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

* add ssf icon

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

* fix web

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

* fix bugs

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

* make events expire, rewrite sending logic

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

* add oidc token test

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

* add stream list

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

* add jwks tests and fixes

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

* update web ui

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

* fix

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

* fix configuration endpoint

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

* replace port number correctly

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

* better log what went wrong

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

* linter has opinions

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

* fix messages

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

* fix set status

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

* more debug logging

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

* fix issuer here too

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

* remove port :443...removal

apparently apple's HTTP logic is wrong and includes the port in the Host header even if the default port is used (80 or 443), which then fails as the URL doesn't exactly match what the admin configured...so instead of trying to add magic about this we'll add it in the docs

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

* fix error when no request in context

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

* add signal for admin session revoke

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

* set txn based on request id

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

* validate method and endpoint url

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

* fix request ID detection

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

* add timestamp

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

* temp migration

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

* fix signal

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

* add signal tests

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

* the final commit

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

* ok actually the last commit

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-05 17:52:14 +01:00
e2d6d3860c core: bump golang.org/x/oauth2 from 0.25.0 to 0.26.0 (#12935)
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.25.0 to 0.26.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  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-02-05 09:32:26 +01:00
91155f9ce3 core: bump golang.org/x/sync from 0.10.0 to 0.11.0 (#12934)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  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-02-05 09:05:06 +01:00
bdcd1059dd core: bump paramiko from 3.5.0 to 3.5.1 (#12931)
Bumps [paramiko](https://github.com/paramiko/paramiko) from 3.5.0 to 3.5.1.
- [Commits](https://github.com/paramiko/paramiko/compare/3.5.0...3.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-04 10:09:21 +01:00
e4b6df3f27 providers/oauth2: include scope in token response (#12921)
* fix scope param missing from token response

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

* fix

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

# Conflicts:
#	authentik/enterprise/providers/ssf/signals.py
#	authentik/enterprise/providers/ssf/tasks.py
#	authentik/enterprise/providers/ssf/tests/test_stream.py

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-03 15:29:26 +01:00
7a6d7919c8 core: bump webauthn from 2.5.0 to 2.5.1 (#12923)
Bumps [webauthn](https://github.com/duo-labs/py_webauthn) from 2.5.0 to 2.5.1.
- [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.0...v2.5.1)

---
updated-dependencies:
- dependency-name: webauthn
  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-02-03 15:04:59 +01:00
fda9b137a7 core: bump ua-parser from 1.0.0 to 1.0.1 (#12922)
Bumps [ua-parser](https://github.com/ua-parser/uap-python) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/ua-parser/uap-python/releases)
- [Commits](https://github.com/ua-parser/uap-python/compare/1.0.0...1.0.1)

---
updated-dependencies:
- dependency-name: ua-parser
  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-02-03 15:02:25 +01:00
7686d12f1b stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#12908)
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-02-01 03:36:50 +01:00
34ee29227a ci: fix daily test (#12909)
* ci: fix daily container test fallback id generation

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

* only attempt to build images when needed

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-01 03:36:30 +01:00
334e2c466f lifecycle: much improved debugging experience (#12804)
* lifecycle: much improved debugging experience

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

* format

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

* add start debug launch configs

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

* only install dev deps in container

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

* add pathMappings

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

* use debugger variable to enable only debugger without debug mode enabled

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

* fix path map

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-02-01 03:35:56 +01:00
7c944b954c core: bump ruff from 0.9.3 to 0.9.4 (#12901)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.3 to 0.9.4.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.9.3...0.9.4)

---
updated-dependencies:
- dependency-name: ruff
  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-01-31 17:15:22 +01:00
427a8c91c8 website/integrations: gitlab to have binding in saml section be post (#12677)
Update index.md to have binding in saml section be post

After upgrading to version 2024.12.2 SAML stopped working in gitlab and was causing 502 errors. After some troubleshooting I finally got it to work again by changing binding to "Post" instead of the recommended "Redirect" in this howto.

Signed-off-by: Nestor N. Camacho III <ncamacho@gmail.com>
2025-01-30 18:37:48 +01:00
22d6dd3098 website/docs: fix 2 links to cobalt restesting pdf (#12895)
* fix link to results

* fix second bad link to pdf

---------

Co-authored-by: Tana M Berry <tana@goauthentik.com>
2025-01-30 18:12:33 +01:00
36c81a30ad core: bump black from 24.10.0 to 25.1.0 (#12889)
* core: bump black from 24.10.0 to 25.1.0

Bumps [black](https://github.com/psf/black) from 24.10.0 to 25.1.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/24.10.0...25.1.0)

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

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-01-30 16:35:03 +01:00
f7dc7faea5 website: bump docusaurus-theme-openapi-docs from 4.3.2 to 4.3.3 in /website (#12887)
website: bump docusaurus-theme-openapi-docs in /website

Bumps [docusaurus-theme-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-theme-openapi-docs) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.3/packages/docusaurus-theme-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-theme-openapi-docs
  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-01-30 14:59:36 +01:00
62720e6c51 core: bump goauthentik.io/api/v3 from 3.2024122.3 to 3.2024123.1 (#12886)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024122.3 to 3.2024123.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.2024122.3...v3.2024123.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-30 14:55:24 +01:00
64dfe7e3c2 website: bump docusaurus-plugin-openapi-docs from 4.3.2 to 4.3.3 in /website (#12888)
website: bump docusaurus-plugin-openapi-docs in /website

Bumps [docusaurus-plugin-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-plugin-openapi-docs) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.3/packages/docusaurus-plugin-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-plugin-openapi-docs
  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-01-30 14:54:37 +01:00
c803b4da51 core: bump dacite from 1.8.1 to 1.9.1 (#12890)
Bumps [dacite](https://github.com/konradhalas/dacite) from 1.8.1 to 1.9.1.
- [Release notes](https://github.com/konradhalas/dacite/releases)
- [Changelog](https://github.com/konradhalas/dacite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/konradhalas/dacite/compare/v1.8.1...v1.9.1)

---
updated-dependencies:
- dependency-name: dacite
  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-01-30 14:48:55 +01:00
3568cd601f web: bump API Client version (#12884)
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-01-30 00:05:25 +01:00
8cad66536c release: 2024.12.3 (#12883)
* release: 2024.12.3

* ci: fix permissions for release-publish pipeline

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

* ci: fix missing dockerhub login

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-01-29 23:35:06 +01:00
220e79e668 ci: fix test_docker.sh (#12880)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-01-29 18:52:30 +01:00
316f43e6eb website/docs: 2024.12.3 release notes (#12871)
* website/docs: 2024.12.3 release notes

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

* fix typo

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-29 18:44:52 +01:00
b7053dfffd ci: fix test_docker.sh (#12878)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-01-29 18:41:58 +01:00
fccdaaf210 core: bump twilio from 9.4.3 to 9.4.4 (#12864)
Bumps [twilio](https://github.com/twilio/twilio-python) from 9.4.3 to 9.4.4.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/9.4.3...9.4.4)

---
updated-dependencies:
- dependency-name: twilio
  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-01-29 18:35:57 +01:00
cf530c6f31 core: bump codespell from 2.4.0 to 2.4.1 (#12865)
Bumps [codespell](https://github.com/codespell-project/codespell) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/codespell-project/codespell/releases)
- [Commits](https://github.com/codespell-project/codespell/compare/v2.4.0...v2.4.1)

---
updated-dependencies:
- dependency-name: codespell
  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-01-29 18:35:48 +01:00
94d84ae1dc core: bump geoip2 from 4.8.1 to 5.0.1 (#12866)
Bumps [geoip2](https://github.com/maxmind/GeoIP2-python) from 4.8.1 to 5.0.1.
- [Release notes](https://github.com/maxmind/GeoIP2-python/releases)
- [Changelog](https://github.com/maxmind/GeoIP2-python/blob/v5.0.1/HISTORY.rst)
- [Commits](https://github.com/maxmind/GeoIP2-python/compare/v4.8.1...v5.0.1)

---
updated-dependencies:
- dependency-name: geoip2
  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-01-29 18:35:37 +01:00
de1bb03619 ci: fix test_docker.sh failing due to empty .env (#12876) 2025-01-29 17:23:32 +00:00
e41d86bd2a ci: fix test_docker.sh failing due to missing .env (#12873)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-29 16:58:51 +01:00
a10e6b7fd7 ci: run full docker test suite in built image on a schedule (#12863)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-29 14:45:07 +01:00
92d6d74c2d lifecycle/migrate: don't migrate tenants if not enabled (#12850) 2025-01-29 12:09:13 +01:00
773c57b8d7 website/integrations-all: add default values change warning (#12777)
* website/integrations-all: add default values change warning

* website/integrations-all: update message

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

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

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

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

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

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

* Update website/integrations/services/hashicorp-cloud/index.md

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

* Update website/integrations/services/hashicorp-vault/index.md

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

* Update website/integrations/services/oracle-cloud/index.md

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

* Update website/integrations/services/hashicorp-vault/index.md

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

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

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

* Update website/integrations/services/proxmox-ve/index.md

Signed-off-by: 4d62 <git@sdko.org>

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

Signed-off-by: 4d62 <git@sdko.org>

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

Signed-off-by: 4d62 <git@sdko.org>

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-29 03:00:39 +00:00
692a6be07f website/integrations: template: add warning about value changes (#12776)
* website/integrations: template: add warning about value changes

* Update website/integrations/template/service.md

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

* Update website/integrations/template/service.md

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

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-28 20:35:29 -06:00
645323cd02 ci: rename use stale label instead of wontfix (#12848)
* ci: rename use stale label instead of wontfix

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* use status prefix

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

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-01-29 00:55:34 +01:00
06d57a7574 website/integrations: owncloud: document (#12540)
* website/integrations: owncloud: init

Apply changes from old MR

* website/integrations: owncloud: easy fixes

Some easy fixes to match template

* website/integrations: owncloud: lint

* website/integrations: owncloud: cleanup authentik configuration section

Cleans up the authentik configuration section of this documentation and removes unneeded bits

* website/integrations: owncloud: adjust authentik configuration headers

Add `### Configuration` header and switch General Settings, Protocl Settings, and Advanced Protocol Settings to H4

* website/integrations: owncloud: update service discovery section & remove unneeded block

Updates the service discovery block to be more in-line with documentation, renames "Apache" to "Apache HTTPD" (correct name), removes provider specific documentation for traefik and instead tells users to view provider-specific docs.

Also removes section kept last commit

* website/integrations: owncloud: start cleanup of "ownCloud configuration" section

Starts cleaning up the steps, adds warning for sub and the other one, grammar, styling and bla bla bla

* website/integrations: owncloud: fix php

Adds single quotes for client-id and client-secret lines. Should be fine I think. Logic says quotes but old docs had none

* i really don't care about a broken anchor netlify

* a

* website/integrations: owncloud: revamp "you're done section"

Cleanup and restructure the section

* website/integrations: owncloud: finish touch-ups

Cleanup the rest of the ownCloud section and update the loginButtonName variable

* website/integrations: owncloud: lint

Lints the code with Prettier

* website/integrations: owncloud: lint

again (?)

* website/integrations: owncloud: v2 authentik configuration section

Applies Tana's suggested format/layout with my suggested modifications. Lint will probably fail so enjoy this nice red cross on the right of this commit :)

Signed-off-by: 4d62 <git@sdko.org>

* website/integrations: owncloud: lint

Yea... That's about it

* Update index.md

Signed-off-by: 4d62 <git@sdko.org>

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

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

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

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

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

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

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

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

* website/integrations: owncloud: remove duplicate

* websites/integrations: owncloud: rewrite sentence for clarity

* website/integrations: owncloud: better OR for how to config oidc

* Fix indent

Signed-off-by: 4d62 <git@sdko.org>

* Lint

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

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

---------

Signed-off-by: 4d62 <git@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-28 17:12:23 -06:00
102c7e4c5c flows: show policy messages in reevaluate marker (#12855)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-28 18:51:50 +01:00
7e7ed83dfe core: bump google-api-python-client from 2.159.0 to 2.160.0 (#12857)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.159.0 to 2.160.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.159.0...v2.160.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  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-01-28 15:43:11 +01:00
141ced8317 website: bump docusaurus-theme-openapi-docs from 4.3.1 to 4.3.2 in /website (#12843)
website: bump docusaurus-theme-openapi-docs in /website

Bumps [docusaurus-theme-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-theme-openapi-docs) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.2/packages/docusaurus-theme-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-theme-openapi-docs
  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-01-27 21:07:23 +01:00
5109af0ab4 website: bump docusaurus-plugin-openapi-docs from 4.3.1 to 4.3.2 in /website (#12844)
website: bump docusaurus-plugin-openapi-docs in /website

Bumps [docusaurus-plugin-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/tree/HEAD/packages/docusaurus-plugin-openapi-docs) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/releases)
- [Changelog](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/commits/v4.3.2/packages/docusaurus-plugin-openapi-docs)

---
updated-dependencies:
- dependency-name: docusaurus-plugin-openapi-docs
  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-01-27 16:03:41 +01:00
1a1912e391 core: bump aws-cdk-lib from 2.176.0 to 2.177.0 (#12842)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-01-27 11:30:39 +00:00
6702652824 lifecycle/aws: bump aws-cdk from 2.176.0 to 2.177.0 in /lifecycle/aws (#12845)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-27 12:05:48 +01:00
b04ff5bbee web: Fix issue where Codemirror partially applies OneDark theme. (#12811)
* web: Fix issue where code mirror partially applies OneDark theme.

- Reported in #4622
- Partially fixed via fd9ce53

* update syntax highlight color when theme is changed

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

* we dont really need to initialise these in the constructor tbh

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-01-25 21:10:12 +01:00
3daa39080a ci: fix container build always attempting to push (#12810)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-25 02:54:03 +01:00
d3d6040e23 lifecycle: better pre release test (#12806)
* move pre-release docker test to script

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

* set pipefail in ak

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

* don't reinstall wheels since they don't exist anymore

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

* fix image

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

* fix config error on startup

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-25 01:38:47 +01:00
e08ccf4ca0 rbac: exclude permissions for internal models (#12803)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-25 01:38:25 +01:00
0e346c6e7c web: bump store2 from 2.14.3 to 2.14.4 in /web (#12805)
Bumps [store2](https://github.com/nbubna/store) from 2.14.3 to 2.14.4.
- [Commits](https://github.com/nbubna/store/compare/2.14.3...2.14.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-25 01:01:49 +01:00
62187e60d4 website: integrations-all: update doc titles to start with "integrate with" (#12775)
* website: integrations-all: update doc titles to start with "integrate with"

* website/integrations-all: cleanup script

* start ??? will do the rest in a sec

* website/integrations-all: fix broken script

website/integrations-all: fix

website/integrations-all: fix

website/integrations-all: fix

website/integrations-all: fix
2025-01-24 15:04:27 -06:00
467b1fcd14 web/flows: fix login / log in inconsistency (#12526)
fix: make "login" vs "log in" consistent
2025-01-24 18:42:29 +01:00
9e2fccb045 flows: clear flow state before redirecting to final URL (#12788)
* providers/oauth2: clear flow state before redirecting to final URL

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

* make flow executor invocation correct

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

* actually we can do this centrally

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

* make sure the state is really clean

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-24 17:01:49 +01:00
39d8b41357 core: bump goauthentik.io/api/v3 from 3.2024122.2 to 3.2024122.3 (#12793)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024122.2 to 3.2024122.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.2024122.2...v3.2024122.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 15:06:56 +01:00
0a0f8433c6 core: bump kubernetes from 31.0.0 to 32.0.0 (#12794)
Bumps [kubernetes](https://github.com/kubernetes-client/python) from 31.0.0 to 32.0.0.
- [Release notes](https://github.com/kubernetes-client/python/releases)
- [Changelog](https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes-client/python/compare/v31.0.0...v32.0.0)

---
updated-dependencies:
- dependency-name: kubernetes
  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-01-24 15:06:47 +01:00
3b61e08d3d core: bump pydantic from 2.10.5 to 2.10.6 (#12795)
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.10.5 to 2.10.6.
- [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.10.5...v2.10.6)

---
updated-dependencies:
- dependency-name: pydantic
  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-01-24 15:06:33 +01:00
921e1923b0 core: bump msgraph-sdk from 1.17.0 to 1.18.0 (#12796)
Bumps [msgraph-sdk](https://github.com/microsoftgraph/msgraph-sdk-python) from 1.17.0 to 1.18.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.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: msgraph-sdk
  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-01-24 15:06:24 +01:00
a666c20c40 core: bump selenium from 4.28.0 to 4.28.1 (#12797)
Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.28.0 to 4.28.1.
- [Release notes](https://github.com/SeleniumHQ/Selenium/releases)
- [Commits](https://github.com/SeleniumHQ/Selenium/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 15:06:11 +01:00
1ed96fd5a5 core: bump ruff from 0.9.2 to 0.9.3 (#12798)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.2 to 0.9.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.9.2...0.9.3)

---
updated-dependencies:
- dependency-name: ruff
  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-01-24 15:05:59 +01:00
f245dada2c website/integrations: Add troubleshooting part to Synology guide (#12681)
* Update index.md

Signed-off-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>

* Update website/integrations/services/synology-dsm/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>

---------

Signed-off-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-24 07:42:41 -06:00
7d8094d9c4 core: fix permissions for admin device listing (#12787)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-24 03:25:07 +01:00
d63cba0a9d website/docs: Flesh out Google Workspaces SAML. (#12701)
* website/docs: Google Workspaces SAML.

- Moves Google Cloud doc page to sibling article.
- Adds Index page for Google sources
- Adds Index page for federated sources

* website/docs: Re-order tags.
2025-01-23 18:26:28 -06:00
fdc3de8646 web: fixes broken docLinks - url missing s (#12789)
fixes broken url-missing s

Co-authored-by: Tana M Berry <tana@goauthentik.com>
2025-01-23 16:13:08 -06:00
7163d333dc lifecycle: update python to 3.12.8 (#12783)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-23 17:04:35 +01:00
02bdf093e0 web: bump API Client version (#12781)
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-01-23 11:53:20 +00:00
1ce3dfd17f sources: allow uuid or slug to be used for retrieving a source (#12780)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-23 12:26:58 +01:00
ce7e539f59 stages/prompt: always show policy messages (#12765)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-23 11:25:09 +01:00
12e6282316 web: bump API Client version (#12768)
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-01-22 23:33:14 +01:00
3253de73ec web: update gen-client-ts to OpenAPI 7.11.0 (#12756)
* 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: Update to OpenAPI 7.11.

This commit updates our Makefile to generate the Typescript api using OpenAPI 7.11, and updates
names (mostly of enum targets) in our product to correspond to the changes in how OpenAPI generates
enum source names.

1. Replaced `ProviderModelEnum.` (note terminal period) with `ProviderModelEnum.AuthentikProvider`.
   For example:

```
-    ProviderModelEnum.SamlSamlprovider
+    ProviderModelEnum.AuthentikProvidersSamlSamlprovider
```

2. Replaced `RbacPermissionsAssignedByUsersListModelEnum.` (note terminal period) with
   `RbacPermissionsAssignedByUsersListModelEnum.Authentik`. For example:

```
-    RbacPermissionsAssignedByUsersListModelEnum.ProvidersLdapLdapprovider.toString(),
+    RbacPermissionsAssignedByUsersListModelEnum.AuthentikProvidersLdapLdapprovider.toString(),
```

3. Replaced `SyncObjectModelEnum.` (note terminal period) with
   `SyncObjectModelEnum.AuthentikCoreModels`. For example:

```
-    model=${SyncObjectModelEnum.Group}
+    model=${SyncObjectModelEnum.AuthentikCoreModelsGroup}
```

4. Replaced `SignatureAlgorithmEnum._` (note terminal symbols) with
   `SignatureAlgorithmEnum.HttpWwwW3Org`. For example:

```
-    ["ECDSA-SHA256", SignatureAlgorithmEnum._200104XmldsigMoreecdsaSha256],
+    ["ECDSA-SHA256", SignatureAlgorithmEnum.HttpWwwW3Org200104XmldsigMoreecdsaSha256],
```

5. Replaced `DigestAlgorithmEnum._` (note terminal symbols) with `DigestAlgorithmEnum.HttpWwwW3Org`.
   For example:

```
-    ["SHA256", DigestAlgorithmEnum._200104Xmlencsha256, true],
+    ["SHA256", DigestAlgorithmEnum.HttpWwwW3Org200104Xmlencsha256, true],
```

6. Replaced `NameIdPolicyEnum._` (note terminal symbols) with
   `NameIdPolicyEnum.UrnOasisNamesTcSaml`. This one is trickier than the others: If you look
   closely, you'll see that how OpenAPI generates the names has changed, with `nameid` now being
   `Nameid`, and `FormatemailAddress` now being `FormatEmailAddress`.

```
-    value=${NameIdPolicyEnum._11nameidFormatemailAddress}
+    value=${NameIdPolicyEnum.UrnOasisNamesTcSaml11NameidFormatEmailAddress}
```

# How

After determining how the enum prefixes had changed, I just ran six of these, testing after each
step to ensure that `npm run lint:types` had fewer errors than the previous run, until the product
built without type errors.

``` sh
$ perl -pi.bak -e 's/DigestAlgorithmEnum\._/DigestAlgorithmEnum.HttpWwwW3Org/' $(rg -l 'DigestAlgorithmEnum\.' src/)
```

# Testing

You can validate that these items have changed by finding the prefixes in the source code and
assuring yourself that every option, checkbox, or radio associated with them is populated correctly.

# User documentation changes required.

None.

# Developer documentation changes required.

None.
2025-01-22 08:15:22 -08:00
afe8ab7850 website/integrations: rustdesk-server-pro (#12706)
* Update sidebarsIntegrations.js

added rustdesk-pro

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Created Rustdesk guide

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* dev stuff + last line... budget?

* missed again... now removed node_modules :D

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Original package.json

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Delete package-lock.json

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Update website/integrations/services/rustdesk-pro/index.mdx

Co-authored-by: 4d62 <git@sdko.org>
Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Update website/integrations/services/rustdesk-pro/index.mdx

Co-authored-by: 4d62 <git@sdko.org>
Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Update website/integrations/services/rustdesk-pro/index.mdx

Co-authored-by: 4d62 <git@sdko.org>
Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* Update website/integrations/services/rustdesk-pro/index.mdx

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

* Update website/integrations/services/rustdesk-pro/index.mdx

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

* Update website/integrations/services/rustdesk-pro/index.mdx

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

---------

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: nicedevil007 <nicedevil007@users.noreply.github.com>
Co-authored-by: 4d62 <git@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-22 16:06:02 +00:00
f2e3199050 core: bump codespell from 2.3.0 to 2.4.0 (#12762)
* core: bump codespell from 2.3.0 to 2.4.0

Bumps [codespell](https://github.com/codespell-project/codespell) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/codespell-project/codespell/releases)
- [Commits](https://github.com/codespell-project/codespell/compare/v2.3.0...v2.4.0)

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

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

* fix

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-01-22 14:52:04 +01:00
04148e08a7 root: docker: ensure apt packages are up-to-date (#12683)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-01-22 14:49:53 +01:00
656b296d6e ci: fix missing build args for dev and release (#12760)
* ci: fix missing build args for dev and release

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

* fix?

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-22 04:13:26 +01:00
f76014710c web: bump vite from 5.4.11 to 5.4.14 in /web (#12757)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.11 to 5.4.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.14/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.14/packages/vite)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 01:49:17 +01:00
04517d46b0 web: bump undici from 6.21.0 to 6.21.1 in /web (#12755)
Bumps [undici](https://github.com/nodejs/undici) from 6.21.0 to 6.21.1.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.21.0...v6.21.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 00:09:31 +01:00
365e9c9ca3 lifecycle: fix cryptography's OpenSSL path (#12753)
* lifecycle: make it work

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

* sigh

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

* I dont know why this works but it works

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-22 00:08:41 +01:00
5b01f44333 stages/redirect: fix query parameter when redirecting to flow (#12750)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-01-21 18:05:23 +01:00
388b29ef87 website/integrations: cloudflare-access: refactor (#12663)
* website/integrations: cloudflare-access: rename

A .mdx file is not needed for this integration. As a result, it has been renamed

* website/integrations: cloudflare access: refactor main document

* website/integrations: cloudflare-access: lint

* Update website/integrations/services/cloudflare-access/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <git@sdko.org>

* website/integrations: all: install -> installation (#12676)

* website/integrations: all: install -> installation

* fix for new integr

Signed-off-by: 4d62 <git@sdko.org>

---------

Signed-off-by: 4d62 <git@sdko.org>

* website/integrations: cloudflare-access: rename

A .mdx file is not needed for this integration. As a result, it has been renamed

---------

Signed-off-by: 4d62 <git@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-01-21 10:55:28 -06:00
401 changed files with 27614 additions and 11371 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.12.2
current_version = 2024.12.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*))?

View File

@ -9,6 +9,9 @@ inputs:
image-arch:
required: false
description: "Docker image arch"
release:
required: true
description: "True if this is a release build, false if this is a dev/PR build"
outputs:
shouldPush:
@ -44,6 +47,9 @@ outputs:
imageMainName:
description: "Docker image main name"
value: ${{ steps.ev.outputs.imageMainName }}
imageBuildArgs:
description: "Docker image build args"
value: ${{ steps.ev.outputs.imageBuildArgs }}
runs:
using: "composite"
@ -54,6 +60,8 @@ runs:
env:
IMAGE_NAME: ${{ inputs.image-name }}
IMAGE_ARCH: ${{ inputs.image-arch }}
RELEASE: ${{ inputs.release }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
REF: ${{ github.ref }}
run: |
python3 ${{ github.action_path }}/push_vars.py

View File

@ -80,6 +80,13 @@ if should_push:
cache_to = f"type=registry,ref={get_attest_image_names(image_tags)}:{_cache_tag},mode=max"
image_build_args = []
if os.getenv("RELEASE", "false").lower() == "true":
image_build_args = [f"VERSION={os.getenv('REF')}"]
else:
image_build_args = [f"GIT_BUILD_HASH={sha}"]
image_build_args = "\n".join(image_build_args)
with open(os.environ["GITHUB_OUTPUT"], "a+", encoding="utf-8") as _output:
print(f"shouldPush={str(should_push).lower()}", file=_output)
print(f"sha={sha}", file=_output)
@ -91,3 +98,4 @@ with open(os.environ["GITHUB_OUTPUT"], "a+", encoding="utf-8") as _output:
print(f"imageMainTag={image_main_tag}", file=_output)
print(f"imageMainName={image_tags[0]}", file=_output)
print(f"cacheTo={cache_to}", file=_output)
print(f"imageBuildArgs={image_build_args}", file=_output)

View File

@ -40,7 +40,7 @@ jobs:
attestations: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3.3.0
- uses: docker/setup-qemu-action@v3.4.0
- uses: docker/setup-buildx-action@v3
- name: prepare variables
uses: ./.github/actions/docker-push-variables
@ -50,6 +50,7 @@ jobs:
with:
image-name: ${{ inputs.image_name }}
image-arch: ${{ inputs.image_arch }}
release: ${{ inputs.release }}
- name: Login to Docker Hub
if: ${{ inputs.registry_dockerhub }}
uses: docker/login-action@v3
@ -76,18 +77,19 @@ jobs:
id: push
with:
context: .
push: true
push: ${{ steps.ev.outputs.shouldPush == 'true' }}
secrets: |
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
build-args: |
VERSION=${{ github.ref }}
${{ steps.ev.outputs.imageBuildArgs }}
tags: ${{ steps.ev.outputs.imageTags }}
platforms: linux/${{ inputs.image_arch }}
cache-from: type=registry,ref=${{ steps.ev.outputs.attestImageNames }}:buildcache-${{ inputs.image_arch }}
cache-to: ${{ steps.ev.outputs.cacheTo }}
- uses: actions/attest-build-provenance@v2
id: attest
if: ${{ steps.ev.outputs.shouldPush == 'true' }}
with:
subject-name: ${{ steps.ev.outputs.attestImageNames }}
subject-digest: ${{ steps.push.outputs.digest }}

View File

@ -46,6 +46,7 @@ jobs:
- build-server-arm64
outputs:
tags: ${{ steps.ev.outputs.imageTagsJSON }}
shouldPush: ${{ steps.ev.outputs.shouldPush }}
steps:
- uses: actions/checkout@v4
- name: prepare variables
@ -57,6 +58,7 @@ jobs:
image-name: ${{ inputs.image_name }}
merge-server:
runs-on: ubuntu-latest
if: ${{ needs.get-tags.outputs.shouldPush == 'true' }}
needs:
- get-tags
- build-server-amd64

28
.github/workflows/ci-main-daily.yml vendored Normal file
View File

@ -0,0 +1,28 @@
---
name: authentik-ci-main-daily
on:
workflow_dispatch:
schedule:
# Every night at 3am
- cron: "0 3 * * *"
jobs:
test-container:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
version:
- docs
- version-2024-12
- version-2024-10
steps:
- uses: actions/checkout@v4
- run: |
current="$(pwd)"
dir="/tmp/authentik/${{ matrix.version }}"
mkdir -p $dir
cd $dir
wget https://${{ matrix.version }}.goauthentik.io/docker-compose.yml
${current}/scripts/test_docker.sh

View File

@ -43,15 +43,26 @@ jobs:
uses: ./.github/actions/setup
- name: run migrations
run: poetry run python -m lifecycle.migrate
test-migrations-from-stable:
name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }}
test-make-seed:
runs-on: ubuntu-latest
steps:
- id: seed
run: |
echo "seed=$(printf "%d\n" "0x$(openssl rand -hex 4)")" >> "$GITHUB_OUTPUT"
outputs:
seed: ${{ steps.seed.outputs.seed }}
test-migrations-from-stable:
name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 20
needs: test-make-seed
strategy:
fail-fast: false
matrix:
psql:
- 15-alpine
- 16-alpine
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
with:
@ -93,18 +104,23 @@ jobs:
env:
# Test in the main database that we just migrated from the previous stable version
AUTHENTIK_POSTGRESQL__TEST__NAME: authentik
CI_TEST_SEED: ${{ needs.test-make-seed.outputs.seed }}
CI_RUN_ID: ${{ matrix.run_id }}
CI_TOTAL_RUNS: "5"
run: |
poetry run make test
poetry run make ci-test
test-unittest:
name: test-unittest - PostgreSQL ${{ matrix.psql }}
name: test-unittest - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 20
needs: test-make-seed
strategy:
fail-fast: false
matrix:
psql:
- 15-alpine
- 16-alpine
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
- name: Setup authentik env
@ -112,9 +128,12 @@ jobs:
with:
postgresql_version: ${{ matrix.psql }}
- name: run unittest
env:
CI_TEST_SEED: ${{ needs.test-make-seed.outputs.seed }}
CI_RUN_ID: ${{ matrix.run_id }}
CI_TOTAL_RUNS: "5"
run: |
poetry run make test
poetry run coverage xml
poetry run make ci-test
- if: ${{ always() }}
uses: codecov/codecov-action@v5
with:

View File

@ -82,7 +82,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0
uses: docker/setup-qemu-action@v3.4.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables

View File

@ -9,9 +9,17 @@ jobs:
build-server:
uses: ./.github/workflows/_reusable-docker-build.yaml
secrets: inherit
permissions:
# Needed to upload container images to ghcr.io
packages: write
# Needed for attestation
id-token: write
attestations: write
with:
image_name: ghcr.io/goauthentik/server,beryju/authentik
release: true
registry_dockerhub: true
registry_ghcr: true
build-outpost:
runs-on: ubuntu-latest
permissions:
@ -34,7 +42,7 @@ jobs:
with:
go-version-file: "go.mod"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0
uses: docker/setup-qemu-action@v3.4.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables

View File

@ -14,16 +14,7 @@ jobs:
- uses: actions/checkout@v4
- name: Pre-release test
run: |
echo "PG_PASS=$(openssl rand 32 | base64 -w 0)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64 -w 0)" >> .env
docker buildx install
mkdir -p ./gen-ts-api
docker build -t testing:latest .
echo "AUTHENTIK_IMAGE=testing" >> .env
echo "AUTHENTIK_TAG=latest" >> .env
docker compose up --no-start
docker compose start postgresql redis
docker compose run -u root server test-all
make test-docker
- id: generate_token
uses: tibdex/github-app-token@v2
with:

View File

@ -1,8 +1,8 @@
name: 'authentik-repo-stale'
name: "authentik-repo-stale"
on:
schedule:
- cron: '30 1 * * *'
- cron: "30 1 * * *"
workflow_dispatch:
permissions:
@ -25,7 +25,7 @@ jobs:
days-before-stale: 60
days-before-close: 7
exempt-issue-labels: pinned,security,pr_wanted,enhancement,bug/confirmed,enhancement/confirmed,question,status/reviewing
stale-issue-label: wontfix
stale-issue-label: status/stale
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you

3
.gitignore vendored
View File

@ -209,3 +209,6 @@ source_docs/
### Golang ###
/vendor/
### Docker ###
docker-compose.override.yml

View File

@ -2,6 +2,7 @@
"recommendations": [
"bashmish.es6-string-css",
"bpruitt-goddard.mermaid-markdown-syntax-highlighting",
"charliermarsh.ruff",
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"esbenp.prettier-vscode",
@ -10,12 +11,12 @@
"Gruntfuggly.todo-tree",
"mechatroner.rainbow-csv",
"ms-python.black-formatter",
"charliermarsh.ruff",
"ms-python.black-formatter",
"ms-python.debugpy",
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"redhat.vscode-yaml",
"Tobermory.es6-string-html",
"unifiedjs.vscode-mdx"
"unifiedjs.vscode-mdx",
]
}

66
.vscode/launch.json vendored
View File

@ -2,26 +2,76 @@
"version": "0.2.0",
"configurations": [
{
"name": "Python: PDB attach Server",
"type": "python",
"name": "Debug: Attach Server Core",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 6800
"port": 9901
},
"justMyCode": true,
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
"django": true
},
{
"name": "Python: PDB attach Worker",
"type": "python",
"name": "Debug: Attach Worker",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 6900
"port": 9901
},
"justMyCode": true,
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
"django": true
},
{
"name": "Debug: Start Server Router",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/server",
"cwd": "${workspaceFolder}"
},
{
"name": "Debug: Start LDAP Outpost",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/ldap",
"cwd": "${workspaceFolder}"
},
{
"name": "Debug: Start Proxy Outpost",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/proxy",
"cwd": "${workspaceFolder}"
},
{
"name": "Debug: Start RAC Outpost",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/rac",
"cwd": "${workspaceFolder}"
},
{
"name": "Debug: Start Radius Outpost",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/radius",
"cwd": "${workspaceFolder}"
}
]
}

View File

@ -94,7 +94,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 5: Python dependencies
FROM ghcr.io/goauthentik/fips-python:3.12.7-slim-bookworm-fips AS python-deps
FROM ghcr.io/goauthentik/fips-python:3.12.8-slim-bookworm-fips AS python-deps
ARG TARGETARCH
ARG TARGETVARIANT
@ -132,13 +132,14 @@ RUN --mount=type=bind,target=./pyproject.toml,src=./pyproject.toml \
. "$HOME/.cargo/env" && \
python -m venv /ak-root/venv/ && \
bash -c "source ${VENV_PATH}/bin/activate && \
pip3 install --upgrade pip && \
pip3 install poetry && \
pip3 install --upgrade pip poetry && \
poetry config --local installer.no-binary cryptography,xmlsec,lxml,python-kadmin-rs && \
poetry install --only=main --no-ansi --no-interaction --no-root && \
pip uninstall cryptography -y && \
poetry install --only=main --no-ansi --no-interaction --no-root"
# Stage 6: Run
FROM ghcr.io/goauthentik/fips-python:3.12.7-slim-bookworm-fips AS final-image
FROM ghcr.io/goauthentik/fips-python:3.12.8-slim-bookworm-fips AS final-image
ARG VERSION
ARG GIT_BUILD_HASH
@ -154,10 +155,12 @@ WORKDIR /
# We cannot cache this layer otherwise we'll end up with a bigger image
RUN apt-get update && \
apt-get upgrade -y && \
# Required for runtime
apt-get install -y --no-install-recommends libpq5 libmaxminddb0 ca-certificates libkrb5-3 libkadm5clnt-mit12 libkdb5-10 libltdl7 libxslt1.1 && \
# Required for bootstrap & healtcheck
apt-get install -y --no-install-recommends runit && \
pip3 install --no-cache-dir --upgrade pip && \
apt-get clean && \
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/ && \
adduser --system --no-create-home --uid 1000 --group --home /authentik authentik && \

View File

@ -6,6 +6,8 @@ UID = $(shell id -u)
GID = $(shell id -g)
NPM_VERSION = $(shell python -m scripts.npm_version)
PY_SOURCES = authentik tests scripts lifecycle .github
GO_SOURCES = cmd internal
WEB_SOURCES = web/src web/packages
DOCKER_IMAGE ?= "authentik:test"
GEN_API_TS = "gen-ts-api"
@ -19,11 +21,12 @@ pg_name := $(shell python -m authentik.lib.config postgresql.name 2>/dev/null)
CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
-I .github/codespell-words.txt \
-S 'web/src/locales/**' \
-S 'website/docs/developer-docs/api/reference/**' \
authentik \
internal \
cmd \
web/src \
-S 'website/developer-docs/api/reference/**' \
-S '**/node_modules/**' \
-S '**/dist/**' \
$(PY_SOURCES) \
$(GO_SOURCES) \
$(WEB_SOURCES) \
website/src \
website/blog \
website/docs \
@ -45,15 +48,6 @@ help: ## Show this help
go-test:
go test -timeout 0 -v -race -cover ./...
test-docker: ## Run all tests in a docker-compose
echo "PG_PASS=$(shell openssl rand 32 | base64 -w 0)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(shell openssl rand 32 | base64 -w 0)" >> .env
docker compose pull -q
docker compose up --no-start
docker compose start postgresql redis
docker compose run -u root server test-all
rm -f .env
test: ## Run the server tests and produce a coverage report (locally)
coverage run manage.py test --keepdb authentik
coverage html
@ -152,7 +146,7 @@ gen-client-ts: gen-clean-ts ## Build and install the authentik API for Typescri
docker run \
--rm -v ${PWD}:/local \
--user ${UID}:${GID} \
docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \
docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \
-i /local/schema.yml \
-g typescript-fetch \
-o /local/${GEN_API_TS} \
@ -263,6 +257,9 @@ docker: ## Build a docker image of the current source tree
mkdir -p ${GEN_API_TS}
DOCKER_BUILDKIT=1 docker build . --progress plain --tag ${DOCKER_IMAGE}
test-docker:
BUILD=true ./scripts/test_docker.sh
#########################
## CI
#########################
@ -287,3 +284,8 @@ ci-bandit: ci--meta-debug
ci-pending-migrations: ci--meta-debug
ak makemigrations --check
ci-test: ci--meta-debug
coverage run manage.py test --keepdb --randomly-seed ${CI_TEST_SEED} authentik
coverage report
coverage xml

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2024.12.2"
__version__ = "2024.12.3"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -51,6 +51,7 @@ from authentik.enterprise.providers.microsoft_entra.models import (
MicrosoftEntraProviderUser,
)
from authentik.enterprise.providers.rac.models import ConnectionToken
from authentik.enterprise.providers.ssf.models import StreamEvent
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
EndpointDevice,
EndpointDeviceConnection,
@ -131,6 +132,7 @@ def excluded_models() -> list[type[Model]]:
EndpointDevice,
EndpointDeviceConnection,
DeviceToken,
StreamEvent,
)

View File

@ -3,6 +3,7 @@
from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from guardian.shortcuts import get_objects_for_user
from rest_framework.fields import (
BooleanField,
CharField,
@ -16,7 +17,6 @@ from rest_framework.viewsets import ViewSet
from authentik.core.api.utils import MetaNameSerializer
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import EndpointDevice
from authentik.rbac.decorators import permission_required
from authentik.stages.authenticator import device_classes, devices_for_user
from authentik.stages.authenticator.models import Device
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
@ -73,7 +73,9 @@ class AdminDeviceViewSet(ViewSet):
def get_devices(self, **kwargs):
"""Get all devices in all child classes"""
for model in device_classes():
device_set = model.objects.filter(**kwargs)
device_set = get_objects_for_user(
self.request.user, f"{model._meta.app_label}.view_{model._meta.model_name}", model
).filter(**kwargs)
yield from device_set
@extend_schema(
@ -86,10 +88,6 @@ class AdminDeviceViewSet(ViewSet):
],
responses={200: DeviceSerializer(many=True)},
)
@permission_required(
None,
[f"{model._meta.app_label}.view_{model._meta.model_name}" for model in device_classes()],
)
def list(self, request: Request) -> Response:
"""Get all devices for current user"""
kwargs = {}

View File

@ -85,7 +85,7 @@ class SourceViewSet(
serializer_class = SourceSerializer
lookup_field = "slug"
search_fields = ["slug", "name"]
filterset_fields = ["slug", "name", "managed"]
filterset_fields = ["slug", "name", "managed", "pbm_uuid"]
def get_queryset(self): # pragma: no cover
return Source.objects.select_subclasses()

View File

@ -236,9 +236,11 @@ class UserSerializer(ModelSerializer):
"path",
"type",
"uuid",
"password_change_date",
]
extra_kwargs = {
"name": {"allow_blank": True},
"password_change_date": {"read_only": True},
}

View File

@ -5,6 +5,7 @@ from typing import TextIO
from daphne.management.commands.runserver import Command as RunServer
from daphne.server import Server
from authentik.lib.debug import start_debug_server
from authentik.root.signals import post_startup, pre_startup, startup
@ -13,6 +14,7 @@ class SignalServer(Server):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
start_debug_server()
def ready_callable():
pre_startup.send(sender=self)

View File

@ -9,6 +9,7 @@ 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()
@ -28,10 +29,7 @@ class Command(BaseCommand):
def handle(self, **options):
LOGGER.debug("Celery options", **options)
close_old_connections()
if CONFIG.get_bool("remote_debug"):
import debugpy
debugpy.listen(("0.0.0.0", 6900)) # nosec
start_debug_server()
worker: Worker = CELERY_APP.Worker(
no_color=False,
quiet=True,

View File

@ -599,6 +599,14 @@ class Application(SerializerModel, PolicyBindingModel):
return None
return candidates[-1]
def backchannel_provider_for[T: Provider](self, provider_type: type[T], **kwargs) -> T | None:
"""Get Backchannel provider for a specific type"""
providers = self.backchannel_providers.filter(
**{f"{provider_type._meta.model_name}__isnull": False},
**kwargs,
)
return getattr(providers.first(), provider_type._meta.model_name)
def __str__(self):
return str(self.name)

View File

@ -0,0 +1,64 @@
"""SSF Provider API Views"""
from django.urls import reverse
from rest_framework.fields import SerializerMethodField
from rest_framework.request import Request
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.tokens import TokenSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.ssf.models import SSFProvider
class SSFProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
"""SSFProvider Serializer"""
ssf_url = SerializerMethodField()
token_obj = TokenSerializer(source="token", required=False, read_only=True)
def get_ssf_url(self, instance: SSFProvider) -> str | None:
request: Request = self._context.get("request")
if not request:
return None
if not instance.backchannel_application:
return None
return request.build_absolute_uri(
reverse(
"authentik_providers_ssf:configuration",
kwargs={
"application_slug": instance.backchannel_application.slug,
},
)
)
class Meta:
model = SSFProvider
fields = [
"pk",
"name",
"component",
"verbose_name",
"verbose_name_plural",
"meta_model_name",
"signing_key",
"token_obj",
"oidc_auth_providers",
"ssf_url",
"event_retention",
]
extra_kwargs = {}
class SSFProviderViewSet(UsedByMixin, ModelViewSet):
"""SSFProvider Viewset"""
queryset = SSFProvider.objects.all()
serializer_class = SSFProviderSerializer
filterset_fields = {
"application": ["isnull"],
"name": ["iexact"],
}
search_fields = ["name"]
ordering = ["name"]

View File

@ -0,0 +1,37 @@
"""SSF Stream API Views"""
from rest_framework.viewsets import ReadOnlyModelViewSet
from authentik.core.api.utils import ModelSerializer
from authentik.enterprise.providers.ssf.api.providers import SSFProviderSerializer
from authentik.enterprise.providers.ssf.models import Stream
class SSFStreamSerializer(ModelSerializer):
"""SSFStream Serializer"""
provider_obj = SSFProviderSerializer(source="provider", read_only=True)
class Meta:
model = Stream
fields = [
"pk",
"provider",
"provider_obj",
"delivery_method",
"endpoint_url",
"events_requested",
"format",
"aud",
"iss",
]
class SSFStreamViewSet(ReadOnlyModelViewSet):
"""SSFStream Viewset"""
queryset = Stream.objects.all()
serializer_class = SSFStreamSerializer
filterset_fields = ["provider", "endpoint_url", "delivery_method"]
search_fields = ["provider__name", "endpoint_url"]
ordering = ["provider", "uuid"]

View File

@ -0,0 +1,13 @@
"""SSF app config"""
from authentik.enterprise.apps import EnterpriseConfig
class AuthentikEnterpriseProviderSSF(EnterpriseConfig):
"""authentik enterprise ssf app config"""
name = "authentik.enterprise.providers.ssf"
label = "authentik_providers_ssf"
verbose_name = "authentik Enterprise.Providers.SSF"
default = True
mountpoint = ""

View File

@ -0,0 +1,201 @@
# Generated by Django 5.0.11 on 2025-02-05 16:20
import authentik.lib.utils.time
import django.contrib.postgres.fields
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("authentik_core", "0042_authenticatedsession_authentik_c_expires_08251d_idx_and_more"),
("authentik_crypto", "0004_alter_certificatekeypair_name"),
("authentik_providers_oauth2", "0027_accesstoken_authentik_p_expires_9f24a5_idx_and_more"),
]
operations = [
migrations.CreateModel(
name="SSFProvider",
fields=[
(
"provider_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_core.provider",
),
),
(
"event_retention",
models.TextField(
default="days=30",
validators=[authentik.lib.utils.time.timedelta_string_validator],
),
),
(
"oidc_auth_providers",
models.ManyToManyField(
blank=True, default=None, to="authentik_providers_oauth2.oauth2provider"
),
),
(
"signing_key",
models.ForeignKey(
help_text="Key used to sign the SSF Events.",
on_delete=django.db.models.deletion.CASCADE,
to="authentik_crypto.certificatekeypair",
verbose_name="Signing Key",
),
),
(
"token",
models.ForeignKey(
default=None,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="authentik_core.token",
),
),
],
options={
"verbose_name": "Shared Signals Framework Provider",
"verbose_name_plural": "Shared Signals Framework Providers",
"permissions": [("add_stream", "Add stream to SSF provider")],
},
bases=("authentik_core.provider",),
),
migrations.CreateModel(
name="Stream",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
),
),
(
"delivery_method",
models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/risc/delivery-method/push",
"Risc Push",
),
(
"https://schemas.openid.net/secevent/risc/delivery-method/poll",
"Risc Poll",
),
]
),
),
("endpoint_url", models.TextField(null=True)),
(
"events_requested",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
"Caep Session Revoked",
),
(
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"Caep Credential Change",
),
(
"https://schemas.openid.net/secevent/ssf/event-type/verification",
"Set Verification",
),
]
),
default=list,
size=None,
),
),
("format", models.TextField()),
(
"aud",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(), default=list, size=None
),
),
("iss", models.TextField()),
(
"provider",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_ssf.ssfprovider",
),
),
],
options={
"verbose_name": "SSF Stream",
"verbose_name_plural": "SSF Streams",
"default_permissions": ["change", "delete", "view"],
},
),
migrations.CreateModel(
name="StreamEvent",
fields=[
("created", models.DateTimeField(auto_now_add=True)),
("last_updated", models.DateTimeField(auto_now=True)),
("expires", models.DateTimeField(default=None, null=True)),
("expiring", models.BooleanField(default=True)),
(
"uuid",
models.UUIDField(
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
),
),
(
"status",
models.TextField(
choices=[
("pending_new", "Pending New"),
("pending_failed", "Pending Failed"),
("sent", "Sent"),
]
),
),
(
"type",
models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
"Caep Session Revoked",
),
(
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"Caep Credential Change",
),
(
"https://schemas.openid.net/secevent/ssf/event-type/verification",
"Set Verification",
),
]
),
),
("payload", models.JSONField(default=dict)),
(
"stream",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_ssf.stream",
),
),
],
options={
"verbose_name": "SSF Stream Event",
"verbose_name_plural": "SSF Stream Events",
"ordering": ("-created",),
},
),
]

View File

@ -0,0 +1,178 @@
from datetime import datetime
from functools import cached_property
from uuid import uuid4
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.templatetags.static import static
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from jwt import encode
from authentik.core.models import BackchannelProvider, ExpiringModel, Token
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
class EventTypes(models.TextChoices):
"""SSF Event types supported by authentik"""
CAEP_SESSION_REVOKED = "https://schemas.openid.net/secevent/caep/event-type/session-revoked"
CAEP_CREDENTIAL_CHANGE = "https://schemas.openid.net/secevent/caep/event-type/credential-change"
SET_VERIFICATION = "https://schemas.openid.net/secevent/ssf/event-type/verification"
class DeliveryMethods(models.TextChoices):
"""SSF Delivery methods"""
RISC_PUSH = "https://schemas.openid.net/secevent/risc/delivery-method/push"
RISC_POLL = "https://schemas.openid.net/secevent/risc/delivery-method/poll"
class SSFEventStatus(models.TextChoices):
"""SSF Event status"""
PENDING_NEW = "pending_new"
PENDING_FAILED = "pending_failed"
SENT = "sent"
class SSFProvider(BackchannelProvider):
"""Shared Signals Framework provider to allow applications to
receive user events from authentik."""
signing_key = models.ForeignKey(
CertificateKeyPair,
verbose_name=_("Signing Key"),
on_delete=models.CASCADE,
help_text=_("Key used to sign the SSF Events."),
)
oidc_auth_providers = models.ManyToManyField(OAuth2Provider, blank=True, default=None)
token = models.ForeignKey(Token, on_delete=models.CASCADE, null=True, default=None)
event_retention = models.TextField(
default="days=30",
validators=[timedelta_string_validator],
)
@cached_property
def jwt_key(self) -> tuple[PrivateKeyTypes, str]:
"""Get either the configured certificate or the client secret"""
key: CertificateKeyPair = self.signing_key
private_key = key.private_key
if isinstance(private_key, RSAPrivateKey):
return private_key, JWTAlgorithms.RS256
if isinstance(private_key, EllipticCurvePrivateKey):
return private_key, JWTAlgorithms.ES256
raise ValueError(f"Invalid private key type: {type(private_key)}")
@property
def service_account_identifier(self) -> str:
return f"ak-providers-ssf-{self.pk}"
@property
def serializer(self):
from authentik.enterprise.providers.ssf.api.providers import SSFProviderSerializer
return SSFProviderSerializer
@property
def icon_url(self) -> str | None:
return static("authentik/sources/ssf.svg")
@property
def component(self) -> str:
return "ak-provider-ssf-form"
class Meta:
verbose_name = _("Shared Signals Framework Provider")
verbose_name_plural = _("Shared Signals Framework Providers")
permissions = [
# This overrides the default "add_stream" permission of the Stream object,
# as the user requesting to add a stream must have the permission on the provider
("add_stream", _("Add stream to SSF provider")),
]
class Stream(models.Model):
"""SSF Stream"""
uuid = models.UUIDField(default=uuid4, primary_key=True, editable=False)
provider = models.ForeignKey(SSFProvider, on_delete=models.CASCADE)
delivery_method = models.TextField(choices=DeliveryMethods.choices)
endpoint_url = models.TextField(null=True)
events_requested = ArrayField(models.TextField(choices=EventTypes.choices), default=list)
format = models.TextField()
aud = ArrayField(models.TextField(), default=list)
iss = models.TextField()
class Meta:
verbose_name = _("SSF Stream")
verbose_name_plural = _("SSF Streams")
default_permissions = ["change", "delete", "view"]
def __str__(self) -> str:
return "SSF Stream"
def prepare_event_payload(self, type: EventTypes, event_data: dict, **kwargs) -> dict:
jti = uuid4()
_now = now()
return {
"uuid": jti,
"stream_id": str(self.pk),
"type": type,
"expiring": True,
"status": SSFEventStatus.PENDING_NEW,
"expires": _now + timedelta_from_string(self.provider.event_retention),
"payload": {
"jti": jti.hex,
"aud": self.aud,
"iat": int(datetime.now().timestamp()),
"iss": self.iss,
"events": {type: event_data},
**kwargs,
},
}
def encode(self, data: dict) -> str:
headers = {}
if self.provider.signing_key:
headers["kid"] = self.provider.signing_key.kid
key, alg = self.provider.jwt_key
return encode(data, key, algorithm=alg, headers=headers)
class StreamEvent(CreatedUpdatedModel, ExpiringModel):
"""Single stream event to be sent"""
uuid = models.UUIDField(default=uuid4, primary_key=True, editable=False)
stream = models.ForeignKey(Stream, on_delete=models.CASCADE)
status = models.TextField(choices=SSFEventStatus.choices)
type = models.TextField(choices=EventTypes.choices)
payload = models.JSONField(default=dict)
def expire_action(self, *args, **kwargs):
"""Only allow automatic cleanup of successfully sent event"""
if self.status != SSFEventStatus.SENT:
return
return super().expire_action(*args, **kwargs)
def __str__(self):
return f"Stream event {self.type}"
class Meta:
verbose_name = _("SSF Stream Event")
verbose_name_plural = _("SSF Stream Events")
ordering = ("-created",)

View File

@ -0,0 +1,193 @@
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 (
USER_PATH_SYSTEM_PREFIX,
AuthenticatedSession,
Token,
TokenIntents,
User,
UserTypes,
)
from authentik.core.signals import password_changed
from authentik.enterprise.providers.ssf.models import (
EventTypes,
SSFProvider,
)
from authentik.enterprise.providers.ssf.tasks import send_ssf_event
from authentik.events.middleware import audit_ignore
from authentik.stages.authenticator.models import Device
from authentik.stages.authenticator_duo.models import DuoDevice
from authentik.stages.authenticator_static.models import StaticDevice
from authentik.stages.authenticator_totp.models import TOTPDevice
from authentik.stages.authenticator_webauthn.models import (
UNKNOWN_DEVICE_TYPE_AAGUID,
WebAuthnDevice,
)
USER_PATH_PROVIDERS_SSF = USER_PATH_SYSTEM_PREFIX + "/providers/ssf"
@receiver(post_save, sender=SSFProvider)
def ssf_providers_post_save(sender: type[Model], instance: SSFProvider, created: bool, **_):
"""Create service account before provider is saved"""
identifier = instance.service_account_identifier
user, _ = User.objects.update_or_create(
username=identifier,
defaults={
"name": f"SSF Provider {instance.name} Service-Account",
"type": UserTypes.INTERNAL_SERVICE_ACCOUNT,
"path": USER_PATH_PROVIDERS_SSF,
},
)
assign_perm("add_stream", user, instance)
token, token_created = Token.objects.update_or_create(
identifier=identifier,
defaults={
"user": user,
"intent": TokenIntents.INTENT_API,
"expiring": False,
"managed": f"goauthentik.io/providers/ssf/{instance.pk}",
},
)
if created or token_created:
with audit_ignore():
instance.token = token
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(
EventTypes.CAEP_SESSION_REVOKED,
{
"initiating_entity": "user",
},
sub_id={
"format": "complex",
"session": {
"format": "opaque",
"id": sha256(instance.session_key.encode("ascii")).hexdigest(),
},
"user": {
"format": "email",
"email": instance.user.email,
},
},
)
@receiver(password_changed)
def ssf_password_changed_cred_change(sender, user: User, password: str | None, **_):
"""Credential change trigger (password changed)"""
send_ssf_event(
EventTypes.CAEP_CREDENTIAL_CHANGE,
{
"credential_type": "password",
"change_type": "revoke" if password is None else "update",
},
sub_id={
"format": "complex",
"user": {
"format": "email",
"email": user.email,
},
},
)
device_type_map = {
StaticDevice: "pin",
TOTPDevice: "pin",
WebAuthnDevice: "fido-u2f",
DuoDevice: "app",
}
@receiver(post_save)
def ssf_device_post_save(sender: type[Model], instance: Device, created: bool, **_):
if not isinstance(instance, Device):
return
if not instance.confirmed:
return
device_type = device_type_map.get(instance.__class__)
data = {
"credential_type": device_type,
"change_type": "create" if created else "update",
"friendly_name": instance.name,
}
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
data["fido2_aaguid"] = instance.aaguid
send_ssf_event(
EventTypes.CAEP_CREDENTIAL_CHANGE,
data,
sub_id={
"format": "complex",
"user": {
"format": "email",
"email": instance.user.email,
},
},
)
@receiver(post_delete)
def ssf_device_post_delete(sender: type[Model], instance: Device, **_):
if not isinstance(instance, Device):
return
if not instance.confirmed:
return
device_type = device_type_map.get(instance.__class__)
data = {
"credential_type": device_type,
"change_type": "delete",
"friendly_name": instance.name,
}
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
data["fido2_aaguid"] = instance.aaguid
send_ssf_event(
EventTypes.CAEP_CREDENTIAL_CHANGE,
data,
sub_id={
"format": "complex",
"user": {
"format": "email",
"email": instance.user.email,
},
},
)

View File

@ -0,0 +1,136 @@
from celery import group
from django.http import HttpRequest
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from requests.exceptions import RequestException
from structlog.stdlib import get_logger
from authentik.core.models import User
from authentik.enterprise.providers.ssf.models import (
DeliveryMethods,
EventTypes,
SSFEventStatus,
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
session = get_http_session()
LOGGER = get_logger()
def send_ssf_event(
event_type: EventTypes,
data: dict,
stream_filter: dict | None = None,
request: HttpRequest | None = None,
**extra_data,
):
"""Wrapper to send an SSF event to multiple streams"""
payload = []
if not stream_filter:
stream_filter = {}
stream_filter["events_requested__contains"] = [event_type]
if request and hasattr(request, "request_id"):
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)
def _check_app_access(stream_uuid: str, 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)
if not email:
return True
user = User.objects.filter(email=email).first()
if not user:
return True
engine = PolicyEngine(stream.provider.backchannel_application, user)
engine.use_cache = False
engine.build()
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()
def send_single_ssf_event(stream_id: str, evt_id: str):
stream = Stream.objects.filter(pk=stream_id).first()
if not stream:
return
event = StreamEvent.objects.filter(pk=evt_id).first()
if not event:
return
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)
return
try:
response = session.post(
event.stream.endpoint_url,
data=event.stream.encode(event.payload),
headers={"Content-Type": "application/secevent+jwt", "Accept": "application/json"},
)
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,
),
)
# Re-up the expiry of the stream event
event.expires = now() + timedelta_from_string(event.stream.provider.event_retention)
event.status = SSFEventStatus.PENDING_FAILED
event.save()

View File

@ -0,0 +1,46 @@
import json
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_cert
from authentik.enterprise.providers.ssf.models import (
SSFProvider,
)
from authentik.lib.generators import generate_id
class TestConfiguration(APITestCase):
def setUp(self):
self.application = Application.objects.create(name=generate_id(), slug=generate_id())
self.provider = SSFProvider.objects.create(
name=generate_id(),
signing_key=create_test_cert(),
backchannel_application=self.application,
)
def test_config_fetch(self):
"""test SSF configuration (unauthenticated)"""
res = self.client.get(
reverse(
"authentik_providers_ssf:configuration",
kwargs={"application_slug": self.application.slug},
),
)
self.assertEqual(res.status_code, 200)
content = json.loads(res.content)
self.assertEqual(content["spec_version"], "1_0-ID2")
def test_config_fetch_authenticated(self):
"""test SSF configuration (authenticated)"""
res = self.client.get(
reverse(
"authentik_providers_ssf:configuration",
kwargs={"application_slug": self.application.slug},
),
HTTP_AUTHORIZATION=f"Bearer {self.provider.token.key}",
)
self.assertEqual(res.status_code, 200)
content = json.loads(res.content)
self.assertEqual(content["spec_version"], "1_0-ID2")

View File

@ -0,0 +1,51 @@
"""JWKS tests"""
import base64
import json
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import load_der_x509_certificate
from django.test import TestCase
from django.urls.base import reverse
from jwt import PyJWKSet
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_cert
from authentik.enterprise.providers.ssf.models import SSFProvider
from authentik.lib.generators import generate_id
class TestJWKS(TestCase):
"""Test JWKS view"""
def test_rs256(self):
"""Test JWKS request with RS256"""
provider = SSFProvider.objects.create(
name=generate_id(),
signing_key=create_test_cert(),
)
app = Application.objects.create(name=generate_id(), slug=generate_id())
app.backchannel_providers.add(provider)
response = self.client.get(
reverse("authentik_providers_ssf:jwks", kwargs={"application_slug": app.slug})
)
body = json.loads(response.content.decode())
self.assertEqual(len(body["keys"]), 1)
PyJWKSet.from_dict(body)
key = body["keys"][0]
load_der_x509_certificate(base64.b64decode(key["x5c"][0]), default_backend()).public_key()
def test_es256(self):
"""Test JWKS request with ES256"""
provider = SSFProvider.objects.create(
name=generate_id(),
signing_key=create_test_cert(),
)
app = Application.objects.create(name=generate_id(), slug=generate_id())
app.backchannel_providers.add(provider)
response = self.client.get(
reverse("authentik_providers_ssf:jwks", kwargs={"application_slug": app.slug})
)
body = json.loads(response.content.decode())
self.assertEqual(len(body["keys"]), 1)
PyJWKSet.from_dict(body)

View File

@ -0,0 +1,168 @@
from uuid import uuid4
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Application, Group
from authentik.core.tests.utils import (
create_test_cert,
create_test_user,
)
from authentik.enterprise.providers.ssf.models import (
EventTypes,
SSFEventStatus,
SSFProvider,
Stream,
StreamEvent,
)
from authentik.lib.generators import generate_id
from authentik.policies.models import PolicyBinding
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
class TestSignals(APITestCase):
"""Test individual SSF Signals"""
def setUp(self):
self.application = Application.objects.create(name=generate_id(), slug=generate_id())
self.provider = SSFProvider.objects.create(
name=generate_id(),
signing_key=create_test_cert(),
backchannel_application=self.application,
)
res = self.client.post(
reverse(
"authentik_providers_ssf:stream",
kwargs={"application_slug": self.application.slug},
),
data={
"iss": "https://authentik.company/.well-known/ssf-configuration/foo/5",
"aud": ["https://app.authentik.company"],
"delivery": {
"method": "https://schemas.openid.net/secevent/risc/delivery-method/push",
"endpoint_url": "https://app.authentik.company",
},
"events_requested": [
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
],
"format": "iss_sub",
},
HTTP_AUTHORIZATION=f"Bearer {self.provider.token.key}",
)
self.assertEqual(res.status_code, 201, res.content)
def test_signal_logout(self):
"""Test user logout"""
user = create_test_user()
self.client.force_login(user)
self.client.logout()
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
event_payload = event.payload["events"][
"https://schemas.openid.net/secevent/caep/event-type/session-revoked"
]
self.assertEqual(event_payload["initiating_entity"], "user")
self.assertEqual(event.payload["sub_id"]["format"], "complex")
self.assertEqual(event.payload["sub_id"]["session"]["format"], "opaque")
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
def test_signal_password_change(self):
"""Test user password change"""
user = create_test_user()
self.client.force_login(user)
user.set_password(generate_id())
user.save()
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
event_payload = event.payload["events"][
"https://schemas.openid.net/secevent/caep/event-type/credential-change"
]
self.assertEqual(event_payload["change_type"], "update")
self.assertEqual(event_payload["credential_type"], "password")
self.assertEqual(event.payload["sub_id"]["format"], "complex")
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
def test_signal_authenticator_added(self):
"""Test authenticator creation signal"""
user = create_test_user()
self.client.force_login(user)
dev = WebAuthnDevice.objects.create(
user=user,
name=generate_id(),
credential_id=generate_id(),
public_key=generate_id(),
aaguid=str(uuid4()),
)
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).exclude().first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
event_payload = event.payload["events"][
"https://schemas.openid.net/secevent/caep/event-type/credential-change"
]
self.assertEqual(event_payload["change_type"], "create")
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
self.assertEqual(event_payload["friendly_name"], dev.name)
self.assertEqual(event_payload["credential_type"], "fido-u2f")
self.assertEqual(event.payload["sub_id"]["format"], "complex")
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
def test_signal_authenticator_deleted(self):
"""Test authenticator deletion signal"""
user = create_test_user()
self.client.force_login(user)
dev = WebAuthnDevice.objects.create(
user=user,
name=generate_id(),
credential_id=generate_id(),
public_key=generate_id(),
aaguid=str(uuid4()),
)
dev.delete()
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).exclude().first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
event_payload = event.payload["events"][
"https://schemas.openid.net/secevent/caep/event-type/credential-change"
]
self.assertEqual(event_payload["change_type"], "delete")
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
self.assertEqual(event_payload["friendly_name"], dev.name)
self.assertEqual(event_payload["credential_type"], "fido-u2f")
self.assertEqual(event.payload["sub_id"]["format"], "complex")
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
def test_signal_policy_ignore(self):
"""Test event not being created for user that doesn't have access to the application"""
PolicyBinding.objects.create(
target=self.application, group=Group.objects.create(name=generate_id()), order=0
)
user = create_test_user()
self.client.force_login(user)
user.set_password(generate_id())
user.save()
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(
stream=stream, type=EventTypes.CAEP_CREDENTIAL_CHANGE
).first()
self.assertIsNone(event)

View File

@ -0,0 +1,154 @@
import json
from dataclasses import asdict
from django.urls import reverse
from django.utils import timezone
from rest_framework.test import APITestCase
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
from authentik.enterprise.providers.ssf.models import (
SSFEventStatus,
SSFProvider,
Stream,
StreamEvent,
)
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.id_token import IDToken
from authentik.providers.oauth2.models import AccessToken, OAuth2Provider
class TestStream(APITestCase):
def setUp(self):
self.application = Application.objects.create(name=generate_id(), slug=generate_id())
self.provider = SSFProvider.objects.create(
name=generate_id(),
signing_key=create_test_cert(),
backchannel_application=self.application,
)
def test_stream_add_token(self):
"""test stream add (token auth)"""
res = self.client.post(
reverse(
"authentik_providers_ssf:stream",
kwargs={"application_slug": self.application.slug},
),
data={
"iss": "https://authentik.company/.well-known/ssf-configuration/foo/5",
"aud": ["https://app.authentik.company"],
"delivery": {
"method": "https://schemas.openid.net/secevent/risc/delivery-method/push",
"endpoint_url": "https://app.authentik.company",
},
"events_requested": [
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
],
"format": "iss_sub",
},
HTTP_AUTHORIZATION=f"Bearer {self.provider.token.key}",
)
self.assertEqual(res.status_code, 201)
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
self.assertEqual(
event.payload["events"],
{"https://schemas.openid.net/secevent/ssf/event-type/verification": {"state": None}},
)
def test_stream_add_poll(self):
"""test stream add - poll method"""
res = self.client.post(
reverse(
"authentik_providers_ssf:stream",
kwargs={"application_slug": self.application.slug},
),
data={
"iss": "https://authentik.company/.well-known/ssf-configuration/foo/5",
"aud": ["https://app.authentik.company"],
"delivery": {
"method": "https://schemas.openid.net/secevent/risc/delivery-method/poll",
},
"events_requested": [
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
],
"format": "iss_sub",
},
HTTP_AUTHORIZATION=f"Bearer {self.provider.token.key}",
)
self.assertEqual(res.status_code, 400)
self.assertJSONEqual(
res.content,
{"delivery": {"method": ["Polling for SSF events is not currently supported."]}},
)
def test_stream_add_oidc(self):
"""test stream add (oidc auth)"""
provider = OAuth2Provider.objects.create(
name=generate_id(),
authorization_flow=create_test_flow(),
)
self.application.provider = provider
self.application.save()
user = create_test_admin_user()
token = AccessToken.objects.create(
provider=provider,
user=user,
token=generate_id(),
auth_time=timezone.now(),
_scope="openid user profile",
_id_token=json.dumps(
asdict(
IDToken("foo", "bar"),
)
),
)
res = self.client.post(
reverse(
"authentik_providers_ssf:stream",
kwargs={"application_slug": self.application.slug},
),
data={
"iss": "https://authentik.company/.well-known/ssf-configuration/foo/5",
"aud": ["https://app.authentik.company"],
"delivery": {
"method": "https://schemas.openid.net/secevent/risc/delivery-method/push",
"endpoint_url": "https://app.authentik.company",
},
"events_requested": [
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
],
"format": "iss_sub",
},
HTTP_AUTHORIZATION=f"Bearer {token.token}",
)
self.assertEqual(res.status_code, 201)
stream = Stream.objects.filter(provider=self.provider).first()
self.assertIsNotNone(stream)
event = StreamEvent.objects.filter(stream=stream).first()
self.assertIsNotNone(event)
self.assertEqual(event.status, SSFEventStatus.PENDING_FAILED)
self.assertEqual(
event.payload["events"],
{"https://schemas.openid.net/secevent/ssf/event-type/verification": {"state": None}},
)
def test_stream_delete(self):
"""delete stream"""
stream = Stream.objects.create(provider=self.provider)
res = self.client.delete(
reverse(
"authentik_providers_ssf:stream",
kwargs={"application_slug": self.application.slug},
),
HTTP_AUTHORIZATION=f"Bearer {self.provider.token.key}",
)
self.assertEqual(res.status_code, 204)
self.assertFalse(Stream.objects.filter(pk=stream.pk).exists())

View File

@ -0,0 +1,32 @@
"""SSF provider URLs"""
from django.urls import path
from authentik.enterprise.providers.ssf.api.providers import SSFProviderViewSet
from authentik.enterprise.providers.ssf.api.streams import SSFStreamViewSet
from authentik.enterprise.providers.ssf.views.configuration import ConfigurationView
from authentik.enterprise.providers.ssf.views.jwks import JWKSview
from authentik.enterprise.providers.ssf.views.stream import StreamView
urlpatterns = [
path(
"application/ssf/<slug:application_slug>/ssf-jwks/",
JWKSview.as_view(),
name="jwks",
),
path(
".well-known/ssf-configuration/<slug:application_slug>",
ConfigurationView.as_view(),
name="configuration",
),
path(
"application/ssf/<slug:application_slug>/stream/",
StreamView.as_view(),
name="stream",
),
]
api_urlpatterns = [
("providers/ssf", SSFProviderViewSet),
("ssf/streams", SSFStreamViewSet),
]

View File

@ -0,0 +1,66 @@
"""SSF Token auth"""
from typing import TYPE_CHECKING, Any
from django.db.models import Q
from rest_framework.authentication import BaseAuthentication, get_authorization_header
from rest_framework.request import Request
from authentik.core.models import Token, TokenIntents, User
from authentik.enterprise.providers.ssf.models import SSFProvider
from authentik.providers.oauth2.models import AccessToken
if TYPE_CHECKING:
from authentik.enterprise.providers.ssf.views.base import SSFView
class SSFTokenAuth(BaseAuthentication):
"""SSF Token auth"""
view: "SSFView"
def __init__(self, view: "SSFView") -> None:
super().__init__()
self.view = view
def check_token(self, key: str) -> Token | None:
"""Check that a token exists, is not expired, and is assigned to the correct provider"""
token = Token.filter_not_expired(key=key, intent=TokenIntents.INTENT_API).first()
if not token:
return None
provider: SSFProvider = token.ssfprovider_set.first()
if not provider:
return None
self.view.application = provider.backchannel_application
self.view.provider = provider
return token
def check_jwt(self, jwt: str) -> AccessToken | None:
"""Check JWT-based authentication, this supports tokens issued either by providers
configured directly in the provider, and by providers assigned to the application
that the SSF provider is a backchannel provider of."""
token = AccessToken.filter_not_expired(token=jwt, revoked=False).first()
if not token:
return None
ssf_provider = SSFProvider.objects.filter(
Q(oidc_auth_providers__in=[token.provider])
| Q(backchannel_application__provider__in=[token.provider]),
).first()
if not ssf_provider:
return None
self.view.application = ssf_provider.backchannel_application
self.view.provider = ssf_provider
return token
def authenticate(self, request: Request) -> tuple[User, Any] | None:
auth = get_authorization_header(request).decode()
auth_type, _, key = auth.partition(" ")
if auth_type != "Bearer":
return None
token = self.check_token(key)
if token:
return (token.user, token)
jwt_token = self.check_jwt(key)
if jwt_token:
return (jwt_token.user, token)
return None

View File

@ -0,0 +1,23 @@
from django.http import HttpRequest
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from structlog.stdlib import BoundLogger, get_logger
from authentik.core.models import Application
from authentik.enterprise.providers.ssf.models import SSFProvider
from authentik.enterprise.providers.ssf.views.auth import SSFTokenAuth
class SSFView(APIView):
application: Application
provider: SSFProvider
logger: BoundLogger
permission_classes = [IsAuthenticated]
def setup(self, request: HttpRequest, *args, **kwargs) -> None:
self.logger = get_logger().bind()
super().setup(request, *args, **kwargs)
def get_authenticators(self):
return [SSFTokenAuth(self)]

View File

@ -0,0 +1,55 @@
from django.http import Http404, HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from rest_framework.permissions import AllowAny
from authentik.core.models import Application
from authentik.enterprise.providers.ssf.models import DeliveryMethods, SSFProvider
from authentik.enterprise.providers.ssf.views.base import SSFView
class ConfigurationView(SSFView):
"""SSF configuration endpoint"""
permission_classes = [AllowAny]
def get_authenticators(self):
return []
def get(self, request: HttpRequest, application_slug: str, *args, **kwargs) -> HttpResponse:
application = get_object_or_404(Application, slug=application_slug)
provider = application.backchannel_provider_for(SSFProvider)
if not provider:
raise Http404
data = {
"spec_version": "1_0-ID2",
"issuer": self.request.build_absolute_uri(
reverse(
"authentik_providers_ssf:configuration",
kwargs={
"application_slug": application.slug,
},
)
),
"jwks_uri": self.request.build_absolute_uri(
reverse(
"authentik_providers_ssf:jwks",
kwargs={
"application_slug": application.slug,
},
)
),
"configuration_endpoint": self.request.build_absolute_uri(
reverse(
"authentik_providers_ssf:stream",
kwargs={
"application_slug": application.slug,
},
)
),
"delivery_methods_supported": [
DeliveryMethods.RISC_PUSH,
],
"authorization_schemes": [{"spec_urn": "urn:ietf:rfc:6749"}],
}
return JsonResponse(data)

View File

@ -0,0 +1,31 @@
from django.http import Http404, HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from django.views import View
from authentik.core.models import Application
from authentik.crypto.models import CertificateKeyPair
from authentik.enterprise.providers.ssf.models import SSFProvider
from authentik.providers.oauth2.views.jwks import JWKSView as OAuthJWKSView
class JWKSview(View):
"""SSF JWKS endpoint, similar to the OAuth2 provider's endpoint"""
def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:
"""Show JWK Key data for Provider"""
application = get_object_or_404(Application, slug=application_slug)
provider = application.backchannel_provider_for(SSFProvider)
if not provider:
raise Http404
signing_key: CertificateKeyPair = provider.signing_key
response_data = {}
jwk = OAuthJWKSView.get_jwk_for_key(signing_key, "sig")
if jwk:
response_data["keys"] = [jwk]
response = JsonResponse(response_data)
response["Access-Control-Allow-Origin"] = "*"
return response

View File

@ -0,0 +1,130 @@
from django.http import HttpRequest
from django.urls import reverse
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.fields import CharField, ChoiceField, ListField, SerializerMethodField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from structlog.stdlib import get_logger
from authentik.core.api.utils import PassiveSerializer
from authentik.enterprise.providers.ssf.models import (
DeliveryMethods,
EventTypes,
SSFProvider,
Stream,
)
from authentik.enterprise.providers.ssf.tasks import send_ssf_event
from authentik.enterprise.providers.ssf.views.base import SSFView
LOGGER = get_logger()
class StreamDeliverySerializer(PassiveSerializer):
method = ChoiceField(choices=[(x.value, x.value) for x in DeliveryMethods])
endpoint_url = CharField(required=False)
def validate_method(self, method: DeliveryMethods):
"""Currently only push is supported"""
if method == DeliveryMethods.RISC_POLL:
raise ValidationError("Polling for SSF events is not currently supported.")
return method
def validate(self, attrs: dict) -> dict:
if attrs["method"] == DeliveryMethods.RISC_PUSH:
if not attrs.get("endpoint_url"):
raise ValidationError("Endpoint URL is required when using push.")
return attrs
class StreamSerializer(ModelSerializer):
delivery = StreamDeliverySerializer()
events_requested = ListField(
child=ChoiceField(choices=[(x.value, x.value) for x in EventTypes])
)
format = CharField()
aud = ListField(child=CharField())
def create(self, validated_data):
provider: SSFProvider = validated_data["provider"]
request: HttpRequest = self.context["request"]
iss = request.build_absolute_uri(
reverse(
"authentik_providers_ssf:configuration",
kwargs={
"application_slug": provider.backchannel_application.slug,
},
)
)
# Ensure that streams always get SET verification events sent to them
validated_data["events_requested"].append(EventTypes.SET_VERIFICATION)
return super().create(
{
"delivery_method": validated_data["delivery"]["method"],
"endpoint_url": validated_data["delivery"].get("endpoint_url"),
"format": validated_data["format"],
"provider": validated_data["provider"],
"events_requested": validated_data["events_requested"],
"aud": validated_data["aud"],
"iss": iss,
}
)
class Meta:
model = Stream
fields = [
"delivery",
"events_requested",
"format",
"aud",
]
class StreamResponseSerializer(PassiveSerializer):
stream_id = CharField(source="pk")
iss = CharField()
aud = ListField(child=CharField())
delivery = SerializerMethodField()
format = CharField()
events_requested = ListField(child=CharField())
events_supported = SerializerMethodField()
events_delivered = ListField(child=CharField(), source="events_requested")
def get_delivery(self, instance: Stream) -> StreamDeliverySerializer:
return {
"method": instance.delivery_method,
"endpoint_url": instance.endpoint_url,
}
def get_events_supported(self, instance: Stream) -> list[str]:
return [x.value for x in EventTypes]
class StreamView(SSFView):
def post(self, request: Request, *args, **kwargs) -> Response:
stream = StreamSerializer(data=request.data, context={"request": request})
stream.is_valid(raise_exception=True)
if not request.user.has_perm("authentik_providers_ssf.add_stream", self.provider):
raise PermissionDenied(
"User does not have permission to create stream for this provider."
)
instance: Stream = stream.save(provider=self.provider)
send_ssf_event(
EventTypes.SET_VERIFICATION,
{
"state": None,
},
stream_filter={"pk": instance.uuid},
sub_id={"format": "opaque", "id": str(instance.uuid)},
)
response = StreamResponseSerializer(instance=instance, context={"request": request}).data
return Response(response, status=201)
def delete(self, request: Request, *args, **kwargs) -> Response:
streams = Stream.objects.filter(provider=self.provider)
# Technically this parameter is required by the spec...
if "stream_id" in request.query_params:
streams = streams.filter(stream_id=request.query_params["stream_id"])
streams.delete()
return Response(status=204)

View File

@ -17,6 +17,7 @@ TENANT_APPS = [
"authentik.enterprise.providers.google_workspace",
"authentik.enterprise.providers.microsoft_entra",
"authentik.enterprise.providers.rac",
"authentik.enterprise.providers.ssf",
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
"authentik.enterprise.stages.source",
]

View File

@ -53,12 +53,13 @@ class SystemTask(TenantTask):
if not isinstance(msg, LogEvent):
self._messages[idx] = LogEvent(msg, logger=self.__name__, log_level="info")
def set_error(self, exception: Exception):
def set_error(self, exception: Exception, *messages: LogEvent):
"""Set result to error and save exception"""
self._status = TaskStatus.ERROR
self._messages = [
LogEvent(exception_to_string(exception), logger=self.__name__, log_level="error")
]
self._messages = list(messages)
self._messages.extend(
[LogEvent(exception_to_string(exception), logger=self.__name__, log_level="error")]
)
def before_start(self, task_id, args, kwargs):
self._start_precise = perf_counter()

View File

@ -3,6 +3,7 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING
from django.contrib.messages import INFO, add_message
from django.http.request import HttpRequest
from structlog.stdlib import get_logger
@ -61,6 +62,8 @@ class ReevaluateMarker(StageMarker):
engine.request.context.update(plan.context)
engine.build()
result = engine.result
for message in result.messages:
add_message(http_request, INFO, message)
if result.passing:
return binding
LOGGER.warning(

View File

@ -109,6 +109,8 @@ class FlowPlan:
def pop(self):
"""Pop next pending stage from bottom of list"""
if not self.markers and not self.bindings:
return
self.markers.pop(0)
self.bindings.pop(0)
@ -156,8 +158,13 @@ class FlowPlan:
final_stage: type[StageView] = self.bindings[-1].stage.view
temp_exec = FlowExecutorView(flow=flow, request=request, plan=self)
temp_exec.current_stage = self.bindings[-1].stage
temp_exec.current_stage_view = final_stage
temp_exec.setup(request, flow.slug)
stage = final_stage(request=request, executor=temp_exec)
return stage.dispatch(request)
response = stage.dispatch(request)
# Ensure we clean the flow state we have in the session before we redirect away
temp_exec.stage_ok()
return response
get_qs = request.GET.copy()
if request.user.is_authenticated and (

View File

@ -103,7 +103,7 @@ class FlowExecutorView(APIView):
permission_classes = [AllowAny]
flow: Flow
flow: Flow = None
plan: FlowPlan | None = None
current_binding: FlowStageBinding | None = None
@ -114,7 +114,8 @@ class FlowExecutorView(APIView):
def setup(self, request: HttpRequest, flow_slug: str):
super().setup(request, flow_slug=flow_slug)
self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
if not self.flow:
self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
self._logger = get_logger().bind(flow_slug=flow_slug)
set_tag("authentik.flow", self.flow.slug)

View File

@ -283,12 +283,15 @@ class ConfigLoader:
def get_optional_int(self, path: str, default=None) -> int | None:
"""Wrapper for get that converts value into int or None if set"""
value = self.get(path, default)
if value is UNSET:
return default
try:
return int(value)
except (ValueError, TypeError) as exc:
if value is None or (isinstance(value, str) and value.lower() == "null"):
return None
return default
if value is UNSET:
return default
self.log("warning", "Failed to parse config as int", path=path, exc=str(exc))
return default
@ -421,4 +424,4 @@ if __name__ == "__main__":
if len(argv) < 2: # noqa: PLR2004
print(dumps(CONFIG.raw, indent=4, cls=AttrEncoder))
else:
print(CONFIG.get(argv[1]))
print(CONFIG.get(argv[-1]))

26
authentik/lib/debug.py Normal file
View File

@ -0,0 +1,26 @@
from structlog.stdlib import get_logger
from authentik.lib.config import CONFIG
LOGGER = get_logger()
def start_debug_server(**kwargs) -> bool:
"""Attempt to start a debugpy server in the current process.
Returns true if the server was started successfully, otherwise false"""
if not CONFIG.get_bool("debug") and not CONFIG.get_bool("debugger"):
return
try:
import debugpy
except ImportError:
LOGGER.warning(
"Failed to import debugpy. debugpy is not included "
"in the default release dependencies and must be installed manually"
)
return False
listen: str = CONFIG.get("listen.listen_debug_py", "127.0.0.1:9901")
host, _, port = listen.rpartition(":")
debugpy.listen((host, int(port)), **kwargs) # nosec
LOGGER.debug("Starting debug server", host=host, port=port)
return True

View File

@ -8,6 +8,7 @@ postgresql:
password: "env://POSTGRES_PASSWORD"
test:
name: test_authentik
default_schema: public
read_replicas: {}
# For example
# 0:
@ -21,6 +22,7 @@ listen:
listen_radius: 0.0.0.0:1812
listen_metrics: 0.0.0.0:9300
listen_debug: 0.0.0.0:9900
listen_debug_py: 0.0.0.0:9901
trusted_proxy_cidrs:
- 127.0.0.0/8
- 10.0.0.0/8
@ -57,7 +59,7 @@ cache:
# transport_options: ""
debug: false
remote_debug: false
debugger: false
log_level: info

View File

@ -22,9 +22,9 @@ class OutgoingSyncProvider(Model):
class Meta:
abstract = True
def client_for_model[
T: User | Group
](self, model: type[T]) -> BaseOutgoingSyncClient[T, Any, Any, Self]:
def client_for_model[T: User | Group](
self, model: type[T]
) -> BaseOutgoingSyncClient[T, Any, Any, Self]:
raise NotImplementedError
def get_object_qs[T: User | Group](self, type: type[T]) -> QuerySet[T]:

View File

@ -42,6 +42,8 @@ class DebugSession(Session):
def get_http_session() -> Session:
"""Get a requests session with common headers"""
session = DebugSession() if CONFIG.get_bool("debug") else Session()
session = Session()
if CONFIG.get_bool("debug") or CONFIG.get("log_level") == "trace":
session = DebugSession()
session.headers["User-Agent"] = authentik_user_agent()
return session

View File

@ -1,11 +1,26 @@
"""Expression Policy API"""
from drf_spectacular.utils import OpenApiResponse, extend_schema
from guardian.shortcuts import get_objects_for_user
from rest_framework.decorators import action
from rest_framework.fields import CharField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger
from authentik.core.api.used_by import UsedByMixin
from authentik.events.logs import LogEventSerializer, capture_logs
from authentik.policies.api.exec import PolicyTestResultSerializer, PolicyTestSerializer
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.expression.evaluator import PolicyEvaluator
from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding
from authentik.policies.process import PolicyProcess
from authentik.policies.types import PolicyRequest
from authentik.rbac.decorators import permission_required
LOGGER = get_logger()
class ExpressionPolicySerializer(PolicySerializer):
@ -30,3 +45,50 @@ class ExpressionPolicyViewSet(UsedByMixin, ModelViewSet):
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class ExpressionPolicyTestSerializer(PolicyTestSerializer):
"""Expression policy test serializer"""
expression = CharField()
@permission_required("authentik_policies.view_policy")
@extend_schema(
request=ExpressionPolicyTestSerializer(),
responses={
200: PolicyTestResultSerializer(),
400: OpenApiResponse(description="Invalid parameters"),
},
)
@action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"])
def test(self, request: Request, pk: str) -> Response:
"""Test policy"""
policy = self.get_object()
test_params = self.ExpressionPolicyTestSerializer(data=request.data)
if not test_params.is_valid():
return Response(test_params.errors, status=400)
# User permission check, only allow policy testing for users that are readable
users = get_objects_for_user(request.user, "authentik_core.view_user").filter(
pk=test_params.validated_data["user"].pk
)
if not users.exists():
return Response(status=400)
policy.expression = test_params.validated_data["expression"]
p_request = PolicyRequest(users.first())
p_request.debug = True
p_request.set_http_request(self.request)
p_request.context = test_params.validated_data.get("context", {})
proc = PolicyProcess(PolicyBinding(policy=policy), p_request, None)
with capture_logs() as logs:
result = proc.execute()
log_messages = []
for log in logs:
if log.attributes.get("process", "") == "PolicyProcess":
continue
log_messages.append(LogEventSerializer(log).data)
result.log_messages = log_messages
response = PolicyTestResultSerializer(result)
return Response(response.data)

View File

@ -281,7 +281,6 @@ class OAuth2Provider(WebfingerProvider, Provider):
},
)
return request.build_absolute_uri(url)
except Provider.application.RelatedObjectDoesNotExist:
return None

View File

@ -1,9 +1,10 @@
from django.contrib.auth.signals import user_logged_out
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.http import HttpRequest
from authentik.core.models import User
from authentik.providers.oauth2.models import AccessToken
from authentik.providers.oauth2.models import AccessToken, DeviceToken, RefreshToken
@receiver(user_logged_out)
@ -12,3 +13,13 @@ def user_logged_out_oauth_access_token(sender, request: HttpRequest, user: User,
if not request.session or not request.session.session_key:
return
AccessToken.objects.filter(user=user, session__session_key=request.session.session_key).delete()
@receiver(post_save, sender=User)
def user_deactivated(sender, instance: User, **_):
"""Remove user tokens when deactivated"""
if instance.is_active:
return
AccessToken.objects.filter(session__user=instance).delete()
RefreshToken.objects.filter(session__user=instance).delete()
DeviceToken.objects.filter(session__user=instance).delete()

View File

@ -150,6 +150,7 @@ class TestToken(OAuthTestCase):
"id_token": provider.encode(
access.id_token.to_dict(),
),
"scope": "",
},
)
self.validate_jwt(access, provider)
@ -242,6 +243,7 @@ class TestToken(OAuthTestCase):
"id_token": provider.encode(
access.id_token.to_dict(),
),
"scope": "offline_access",
},
)
self.validate_jwt(access, provider)
@ -301,6 +303,7 @@ class TestToken(OAuthTestCase):
"id_token": provider.encode(
access.id_token.to_dict(),
),
"scope": "offline_access",
},
)

View File

@ -499,11 +499,11 @@ class OAuthFulfillmentStage(StageView):
)
challenge.is_valid()
self.executor.stage_ok()
return HttpChallengeResponse(
challenge=challenge,
)
self.executor.stage_ok()
return HttpResponseRedirectScheme(uri, allowed_schemes=[parsed.scheme])
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:

View File

@ -64,7 +64,8 @@ def to_base64url_uint(val: int, min_length: int = 0) -> bytes:
class JWKSView(View):
"""Show RSA Key data for Provider"""
def get_jwk_for_key(self, key: CertificateKeyPair, use: str) -> dict | None:
@staticmethod
def get_jwk_for_key(key: CertificateKeyPair, use: str) -> dict | None:
"""Convert a certificate-key pair into JWK"""
private_key = key.private_key
key_data = None
@ -123,12 +124,12 @@ class JWKSView(View):
response_data = {}
if signing_key := provider.signing_key:
jwk = self.get_jwk_for_key(signing_key, "sig")
jwk = JWKSView.get_jwk_for_key(signing_key, "sig")
if jwk:
response_data.setdefault("keys", [])
response_data["keys"].append(jwk)
if encryption_key := provider.encryption_key:
jwk = self.get_jwk_for_key(encryption_key, "enc")
jwk = JWKSView.get_jwk_for_key(encryption_key, "enc")
if jwk:
response_data.setdefault("keys", [])
response_data["keys"].append(jwk)

View File

@ -627,6 +627,7 @@ class TokenView(View):
response = {
"access_token": access_token.token,
"token_type": TOKEN_TYPE,
"scope": " ".join(access_token.scope),
"expires_in": int(
timedelta_from_string(self.provider.access_token_validity).total_seconds()
),
@ -710,6 +711,7 @@ class TokenView(View):
"access_token": access_token.token,
"refresh_token": refresh_token.token,
"token_type": TOKEN_TYPE,
"scope": " ".join(access_token.scope),
"expires_in": int(
timedelta_from_string(self.provider.access_token_validity).total_seconds()
),
@ -736,6 +738,7 @@ class TokenView(View):
return {
"access_token": access_token.token,
"token_type": TOKEN_TYPE,
"scope": " ".join(access_token.scope),
"expires_in": int(
timedelta_from_string(self.provider.access_token_validity).total_seconds()
),
@ -767,6 +770,7 @@ class TokenView(View):
response = {
"access_token": access_token.token,
"token_type": TOKEN_TYPE,
"scope": " ".join(access_token.scope),
"expires_in": int(
timedelta_from_string(self.provider.access_token_validity).total_seconds()
),

View File

@ -2,7 +2,7 @@
from django.apps import apps
from django.contrib.auth.models import Permission
from django.db.models import QuerySet
from django.db.models import Q, QuerySet
from django_filters.filters import ModelChoiceFilter
from django_filters.filterset import FilterSet
from django_filters.rest_framework import DjangoFilterBackend
@ -18,6 +18,7 @@ from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ReadOnlyModelViewSet
from authentik.blueprints.v1.importer import excluded_models
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
from authentik.core.models import User
from authentik.lib.validators import RequiredTogetherValidator
@ -105,13 +106,13 @@ class RBACPermissionViewSet(ReadOnlyModelViewSet):
]
def get_queryset(self) -> QuerySet:
return (
Permission.objects.all()
.select_related("content_type")
.filter(
content_type__app_label__startswith="authentik",
query = Q()
for model in excluded_models():
query |= Q(
content_type__app_label=model._meta.app_label,
content_type__model=model._meta.model_name,
)
)
return Permission.objects.all().select_related("content_type").exclude(query)
class PermissionAssignSerializer(PassiveSerializer):

View File

@ -7,7 +7,12 @@ from psycopg import connect
from authentik.lib.config import CONFIG
QUERY = """SELECT id FROM public.authentik_install_id ORDER BY id LIMIT 1;"""
# We need to string format the query as tables and schemas can't be set by parameters
# not a security issue as the config value is set by the person installing authentik
# which also has postgres credentials etc
QUERY = """SELECT id FROM {}.authentik_install_id ORDER BY id LIMIT 1;""".format( # nosec
CONFIG.get("postgresql.default_schema")
)
@lru_cache

View File

@ -129,6 +129,7 @@ TENANT_DOMAIN_MODEL = "authentik_tenants.Domain"
TENANT_CREATION_FAKES_MIGRATIONS = True
TENANT_BASE_SCHEMA = "template"
PUBLIC_SCHEMA_NAME = CONFIG.get("postgresql.default_schema")
GUARDIAN_MONKEY_PATCH = False

View File

@ -1,3 +1,4 @@
import math
from os import environ
from ssl import OPENSSL_VERSION
@ -24,3 +25,20 @@ def pytest_report_header(*_, **__):
f"authentik version: {get_full_version()}",
f"OpenSSL version: {OPENSSL_VERSION}, FIPS: {backend._fips_enabled}",
]
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
current_id = int(environ.get("CI_RUN_ID", 0)) - 1
total_ids = int(environ.get("CI_TOTAL_RUNS", 0))
if total_ids:
num_tests = len(items)
matrix_size = math.ceil(num_tests / total_ids)
start = current_id * matrix_size
end = (current_id + 1) * matrix_size
deselected_items = items[:start] + items[end:]
config.hook.pytest_deselected(items=deselected_items)
items[:] = items[start:end]
print(f" Executing {start} - {end} tests")

View File

@ -66,6 +66,7 @@ class KerberosSourceViewSet(UsedByMixin, ModelViewSet):
serializer_class = KerberosSourceSerializer
lookup_field = "slug"
filterset_fields = [
"pbm_uuid",
"name",
"slug",
"enabled",

View File

@ -110,6 +110,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
serializer_class = LDAPSourceSerializer
lookup_field = "slug"
filterset_fields = [
"pbm_uuid",
"name",
"slug",
"enabled",

View File

@ -152,6 +152,7 @@ class OAuthSourceFilter(FilterSet):
class Meta:
model = OAuthSource
fields = [
"pbm_uuid",
"name",
"slug",
"enabled",

View File

@ -52,6 +52,7 @@ class PlexSourceViewSet(UsedByMixin, ModelViewSet):
serializer_class = PlexSourceSerializer
lookup_field = "slug"
filterset_fields = [
"pbm_uuid",
"name",
"slug",
"enabled",

View File

@ -44,6 +44,7 @@ class SAMLSourceViewSet(UsedByMixin, ModelViewSet):
serializer_class = SAMLSourceSerializer
lookup_field = "slug"
filterset_fields = [
"pbm_uuid",
"name",
"slug",
"enabled",

View File

@ -53,6 +53,6 @@ class SCIMSourceViewSet(UsedByMixin, ModelViewSet):
queryset = SCIMSource.objects.all()
serializer_class = SCIMSourceSerializer
lookup_field = "slug"
filterset_fields = ["name", "slug"]
filterset_fields = ["pbm_uuid", "name", "slug"]
search_fields = ["name", "slug", "token__identifier", "token__user__username"]
ordering = ["name"]

View File

@ -114,7 +114,7 @@ class SCIMView(APIView):
class SCIMObjectView(SCIMView):
"""Base SCIM View for object management"""
"""Base SCIM View for object management"""
mapper: SourceMapper
manager: PropertyMappingManager

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@ from email.policy import Policy
from types import MethodType
from typing import Any
from django.contrib.messages import INFO, add_message
from django.db.models.query import QuerySet
from django.http import HttpRequest, HttpResponse
from django.http.request import QueryDict
@ -147,6 +148,9 @@ class PromptChallengeResponse(ChallengeResponse):
result = engine.result
if not result.passing:
raise ValidationError(list(result.messages))
else:
for msg in result.messages:
add_message(self.request, INFO, msg)
return attrs

View File

@ -20,7 +20,7 @@ from authentik.flows.planner import (
FlowPlanner,
)
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_PLAN, InvalidStageError
from authentik.flows.views.executor import SESSION_KEY_GET, SESSION_KEY_PLAN, InvalidStageError
from authentik.lib.utils.urls import reverse_with_qs
from authentik.stages.redirect.models import RedirectMode, RedirectStage
@ -72,7 +72,9 @@ class RedirectStageView(ChallengeStageView):
self.request.session[SESSION_KEY_PLAN] = plan
kwargs = self.executor.kwargs
kwargs.update({"flow_slug": flow.slug})
return reverse_with_qs("authentik_core:if-flow", self.request.GET, kwargs=kwargs)
return reverse_with_qs(
"authentik_core:if-flow", self.request.session[SESSION_KEY_GET], kwargs=kwargs
)
def get_challenge(self, *args, **kwargs) -> Challenge:
"""Get the redirect target. Prioritize `redirect_stage_target` if present."""

View File

@ -1,5 +1,7 @@
"""Test Redirect stage"""
from urllib.parse import urlencode
from django.urls.base import reverse
from rest_framework.exceptions import ValidationError
@ -58,6 +60,23 @@ class TestRedirectStage(FlowTestCase):
response, reverse("authentik_core:if-flow", kwargs={"flow_slug": self.target_flow.slug})
)
def test_flow_query(self):
self.stage.mode = RedirectMode.FLOW
self.stage.save()
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
+ "?"
+ urlencode({"query": urlencode({"test": "foo"})})
)
self.assertStageRedirects(
response,
reverse("authentik_core:if-flow", kwargs={"flow_slug": self.target_flow.slug})
+ "?"
+ urlencode({"test": "foo"}),
)
def test_override_static(self):
policy = ExpressionPolicy.objects.create(
name=generate_id(),

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2024.12.2 Blueprint schema",
"title": "authentik 2024.12.3 Blueprint schema",
"required": [
"version",
"entries"
@ -3601,6 +3601,46 @@
}
}
},
{
"type": "object",
"required": [
"model",
"identifiers"
],
"properties": {
"model": {
"const": "authentik_providers_ssf.ssfprovider"
},
"id": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"absent",
"present",
"created",
"must_created"
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"permissions": {
"$ref": "#/$defs/model_authentik_providers_ssf.ssfprovider_permissions"
},
"attrs": {
"$ref": "#/$defs/model_authentik_providers_ssf.ssfprovider"
},
"identifiers": {
"$ref": "#/$defs/model_authentik_providers_ssf.ssfprovider"
}
}
},
{
"type": "object",
"required": [
@ -4583,6 +4623,7 @@
"authentik.enterprise.providers.google_workspace",
"authentik.enterprise.providers.microsoft_entra",
"authentik.enterprise.providers.rac",
"authentik.enterprise.providers.ssf",
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
"authentik.enterprise.stages.source",
"authentik.events"
@ -4686,6 +4727,7 @@
"authentik_providers_rac.racprovider",
"authentik_providers_rac.endpoint",
"authentik_providers_rac.racpropertymapping",
"authentik_providers_ssf.ssfprovider",
"authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
"authentik_stages_source.sourcestage",
"authentik_events.event",
@ -6687,6 +6729,18 @@
"authentik_providers_scim.view_scimprovider",
"authentik_providers_scim.view_scimprovidergroup",
"authentik_providers_scim.view_scimprovideruser",
"authentik_providers_ssf.add_ssfprovider",
"authentik_providers_ssf.add_stream",
"authentik_providers_ssf.add_streamevent",
"authentik_providers_ssf.change_ssfprovider",
"authentik_providers_ssf.change_stream",
"authentik_providers_ssf.change_streamevent",
"authentik_providers_ssf.delete_ssfprovider",
"authentik_providers_ssf.delete_stream",
"authentik_providers_ssf.delete_streamevent",
"authentik_providers_ssf.view_ssfprovider",
"authentik_providers_ssf.view_stream",
"authentik_providers_ssf.view_streamevent",
"authentik_rbac.access_admin_interface",
"authentik_rbac.add_role",
"authentik_rbac.assign_role_permissions",
@ -12936,6 +12990,18 @@
"authentik_providers_scim.view_scimprovider",
"authentik_providers_scim.view_scimprovidergroup",
"authentik_providers_scim.view_scimprovideruser",
"authentik_providers_ssf.add_ssfprovider",
"authentik_providers_ssf.add_stream",
"authentik_providers_ssf.add_streamevent",
"authentik_providers_ssf.change_ssfprovider",
"authentik_providers_ssf.change_stream",
"authentik_providers_ssf.change_streamevent",
"authentik_providers_ssf.delete_ssfprovider",
"authentik_providers_ssf.delete_stream",
"authentik_providers_ssf.delete_streamevent",
"authentik_providers_ssf.view_ssfprovider",
"authentik_providers_ssf.view_stream",
"authentik_providers_ssf.view_streamevent",
"authentik_rbac.access_admin_interface",
"authentik_rbac.add_role",
"authentik_rbac.assign_role_permissions",
@ -13988,6 +14054,62 @@
}
}
},
"model_authentik_providers_ssf.ssfprovider": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"title": "Name"
},
"signing_key": {
"type": "string",
"format": "uuid",
"title": "Signing Key",
"description": "Key used to sign the SSF Events."
},
"oidc_auth_providers": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Oidc auth providers"
},
"event_retention": {
"type": "string",
"minLength": 1,
"title": "Event retention"
}
},
"required": []
},
"model_authentik_providers_ssf.ssfprovider_permissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"permission"
],
"properties": {
"permission": {
"type": "string",
"enum": [
"add_stream",
"add_ssfprovider",
"change_ssfprovider",
"delete_ssfprovider",
"view_ssfprovider"
]
},
"user": {
"type": "integer"
},
"role": {
"type": "string"
}
}
}
},
"model_authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage": {
"type": "object",
"properties": {

View File

@ -31,7 +31,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
restart: unless-stopped
command: server
environment:
@ -54,7 +54,7 @@ services:
redis:
condition: service_healthy
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
restart: unless-stopped
command: worker
environment:

8
go.mod
View File

@ -24,15 +24,15 @@ require (
github.com/pires/go-proxyproto v0.8.0
github.com/prometheus/client_golang v1.20.5
github.com/redis/go-redis/v9 v9.7.0
github.com/sethvargo/go-envconfig v1.1.0
github.com/sethvargo/go-envconfig v1.1.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.10.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2024122.2
goauthentik.io/api/v3 v3.2024123.4
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.25.0
golang.org/x/sync v0.10.0
golang.org/x/oauth2 v0.26.0
golang.org/x/sync v0.11.0
gopkg.in/yaml.v2 v2.4.0
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
)

15
go.sum
View File

@ -254,8 +254,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sethvargo/go-envconfig v1.1.0 h1:cWZiJxeTm7AlCvzGXrEXaSTCNgip5oJepekh/BOQuog=
github.com/sethvargo/go-envconfig v1.1.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
github.com/sethvargo/go-envconfig v1.1.1 h1:JDu8Q9baIzJf47NPkzhIB6aLYL0vQ+pPypoYrejS9QY=
github.com/sethvargo/go-envconfig v1.1.1/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@ -299,8 +299,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
goauthentik.io/api/v3 v3.2024122.2 h1:QC+ZQ+AxlPwl9OG1X/Z62EVepmTGyfvJUxhUdFjs+4s=
goauthentik.io/api/v3 v3.2024122.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2024123.4 h1:JYLsUjkJ7kT+jHO72DyFTXFwKEGAcOOlLh36SRG9BDw=
goauthentik.io/api/v3 v3.2024123.4/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -393,8 +393,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -408,8 +408,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion())
}
const VERSION = "2024.12.2"
const VERSION = "2024.12.3"

View File

@ -15,7 +15,6 @@ import (
func EnableDebugServer() {
l := log.WithField("logger", "authentik.go_debugger")
if !config.Get().Debug {
l.Info("not enabling debug server, set `AUTHENTIK_DEBUG` to `true` to enable it.")
return
}
h := mux.NewRouter()

View File

@ -43,6 +43,11 @@ LABEL org.opencontainers.image.source=https://github.com/goauthentik/authentik
LABEL org.opencontainers.image.version=${VERSION}
LABEL org.opencontainers.image.revision=${GIT_BUILD_HASH}
RUN apt-get update && \
apt-get upgrade -y && \
apt-get clean && \
rm -rf /tmp/* /var/lib/apt/lists/*
COPY --from=builder /go/ldap /
HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/ldap", "healthcheck" ]

View File

@ -1,4 +1,5 @@
#!/usr/bin/env -S bash -e
#!/usr/bin/env -S bash
set -e -o pipefail
MODE_FILE="${TMPDIR}/authentik-mode"
function log {
@ -54,6 +55,10 @@ function cleanup {
}
function prepare_debug {
# Only attempt to install debug dependencies if we're running in a container
if [ ! -d /ak-root ]; then
return
fi
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends krb5-kdc krb5-user krb5-admin-server libkrb5-dev gcc
@ -62,7 +67,7 @@ function prepare_debug {
chown authentik:authentik /unittest.xml
}
if [[ "${AUTHENTIK_REMOTE_DEBUG}" == "true" ]]; then
if [[ "$(python -m authentik.lib.config debugger 2> /dev/null)" == "True" ]]; then
prepare_debug
fi
@ -87,12 +92,11 @@ elif [[ "$1" == "bash" ]]; then
elif [[ "$1" == "test-all" ]]; then
prepare_debug
chmod 777 /root
pip install --force-reinstall /wheels/*
check_if_root "python -m manage test authentik"
elif [[ "$1" == "healthcheck" ]]; then
run_authentik healthcheck $(cat $MODE_FILE)
elif [[ "$1" == "dump_config" ]]; then
exec python -m authentik.lib.config
exec python -m authentik.lib.config $@
elif [[ "$1" == "debug" ]]; then
exec sleep infinity
else

View File

@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "MIT",
"devDependencies": {
"aws-cdk": "^2.176.0",
"aws-cdk": "^2.178.2",
"cross-env": "^7.0.3"
},
"engines": {
@ -17,9 +17,9 @@
}
},
"node_modules/aws-cdk": {
"version": "2.176.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.176.0.tgz",
"integrity": "sha512-yRjIXzK2ddznwuSjasWAViYBtBSQbEu6GHlylaC3GHsIUPhrK3KguqIuhdlxjMeiQ1Fvok8REDLCReZJdrSLLg==",
"version": "2.178.2",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.178.2.tgz",
"integrity": "sha512-ojMCMnBGinvDUD6+BOOlUOB9pjsYXoQdFVbf4bvi3dy3nwn557r0j6qDUcJMeikzPJ6YWzfAdL0fYxBZg4xcOg==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@ -10,7 +10,7 @@
"node": ">=20"
},
"devDependencies": {
"aws-cdk": "^2.176.0",
"aws-cdk": "^2.178.2",
"cross-env": "^7.0.3"
}
}

View File

@ -26,7 +26,7 @@ Parameters:
Description: authentik Docker image
AuthentikVersion:
Type: String
Default: 2024.12.2
Default: 2024.12.3
Description: authentik Docker image tag
AuthentikServerCPU:
Type: Number

View File

@ -13,6 +13,7 @@ from prometheus_client.values import MultiProcessValue
from authentik import get_full_version
from authentik.lib.config import CONFIG
from authentik.lib.debug import start_debug_server
from authentik.lib.logging import get_logger_config
from authentik.lib.utils.http import get_http_session
from authentik.lib.utils.reflection import get_env
@ -146,9 +147,5 @@ if not CONFIG.get_bool("disable_startup_analytics", False):
except Exception: # nosec
pass
if CONFIG.get_bool("remote_debug"):
import debugpy
debugpy.listen(("0.0.0.0", 6800)) # nosec
start_debug_server()
run_migrations()

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
"""System Migration handler"""
from importlib.util import module_from_spec, spec_from_file_location
from inspect import getmembers, isclass
from os import environ, system
@ -112,7 +113,8 @@ def run_migrations():
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(["", "migrate_schemas"])
execute_from_command_line(["", "migrate_schemas", "--schema", "template", "--tenant"])
if CONFIG.get_bool("tenants.enabled", False):
execute_from_command_line(["", "migrate_schemas", "--schema", "template", "--tenant"])
execute_from_command_line(
["", "check"] + ([] if CONFIG.get_bool("debug") else ["--deploy"])
)

Binary file not shown.

View File

@ -26,17 +26,20 @@
# Thomas Liske, 2024
# Michael Gottinger, 2024
# itxworks, 2024
# Alexander Möbius, 2024
# Christian Wichmann <cw1981@gmx.de>, 2024
# Stefan Werner, 2024
# Alexander Möbius, 2025
# Jonas, 2025
# Niklas Kroese, 2025
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-18 00:09+0000\n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Christian Wichmann <cw1981@gmx.de>, 2024\n"
"Last-Translator: Niklas Kroese, 2025\n"
"Language-Team: German (https://app.transifex.com/authentik/teams/119923/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -104,9 +107,9 @@ msgid "authentik Export - {date}"
msgstr "authentik Export - {date}"
#: authentik/blueprints/v1/tasks.py authentik/crypto/tasks.py
#, python-format
msgid "Successfully imported %(count)d files."
msgstr "%(count)d Dateien wurden erfolgreich importiert."
#, python-brace-format
msgid "Successfully imported {count} files."
msgstr "{count} Dateien erfolgreich importiert."
#: authentik/brands/models.py
msgid ""
@ -136,6 +139,10 @@ msgstr "Marke"
msgid "Brands"
msgstr "Marken"
#: authentik/core/api/application_entitlements.py
msgid "User does not have access to application."
msgstr "Nutzer hat keinen Zugriff auf diese Applikation."
#: authentik/core/api/devices.py
msgid "Extra description not available"
msgstr "Eine weitergehende Beschreibung ist nicht verfügbar"
@ -269,6 +276,14 @@ msgstr "Anwendung"
msgid "Applications"
msgstr "Anwendungen"
#: authentik/core/models.py
msgid "Application Entitlement"
msgstr "Anwendungsberechtigung"
#: authentik/core/models.py
msgid "Application Entitlements"
msgstr "Anwendungsberechtigungen"
#: authentik/core/models.py
msgid "Use the source-specific identifier"
msgstr "Verwenden Sie die quellenspezifische Kennung"
@ -611,6 +626,47 @@ msgstr "Maximale Verbindungsgrenze erreicht."
msgid "(You are already connected in another tab/window)"
msgstr "(Sie sind bereits in einem anderen Tab/Fenster verbunden)"
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Signaturschlüssel"
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr ""
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr ""
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr "Endpunkt-Authenticator für Google Gerätevertrauen Verbindungs Stage"
@ -908,9 +964,8 @@ msgstr ""
"Evaluierung der Richtlinien während des Planungsprozesses für den Flow."
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is present to the user."
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
"Bewerten Sie die Richtlinien, wenn die Stufe für den Benutzer sichtbar ist."
#: authentik/flows/models.py
msgid ""
@ -959,14 +1014,14 @@ msgid "Starting full provider sync"
msgstr "Starte komplette Provider Synchronisation."
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "Seite %(page)d der Benutzer synchronisieren"
#, python-brace-format
msgid "Syncing page {page} of users"
msgstr "Synchonisiere Benutzer Seite {page}"
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "Seite %(page)d der Gruppen synchronisieren"
#, python-brace-format
msgid "Syncing page {page} of groups"
msgstr "Synchonisiere Gruppen Seite {page}"
#: authentik/lib/sync/outgoing/tasks.py
#, python-brace-format
@ -1140,10 +1195,10 @@ msgid "Event Matcher Policies"
msgstr "Richtlinie für den Ereignisvergleich"
#: authentik/policies/expiry/models.py
#, python-format
msgid "Password expired %(days)d days ago. Please update your password."
#, python-brace-format
msgid "Password expired {days} days ago. Please update your password."
msgstr ""
"Das Passwort ist vor %(days)d Tagen abgelaufen. Bitte aktualisieren Sie Ihr "
"Das Passwort ist vor {days} Tagen abgelaufen. Bitte aktualisieren Sie Ihr "
"Passwort."
#: authentik/policies/expiry/models.py
@ -1278,9 +1333,9 @@ msgid "Invalid password."
msgstr "Ungültiges Passwort."
#: authentik/policies/password/models.py
#, python-format
msgid "Password exists on %(count)d online lists."
msgstr "Passwort existiert auf %(count)d Listen."
#, python-brace-format
msgid "Password exists on {count} online lists."
msgstr "Passwort online in {count} Listen gefunden."
#: authentik/policies/password/models.py
msgid "Password is too weak."
@ -1407,6 +1462,11 @@ msgstr "LDAP Anbietern"
msgid "Search full LDAP directory"
msgstr "Durchsuche komplettes LDAP Verzeichnis"
#: authentik/providers/oauth2/api/providers.py
#, python-brace-format
msgid "Invalid Regex Pattern: {url}"
msgstr "Regex pattern ungültig: {url}"
#: authentik/providers/oauth2/id_token.py
msgid "Based on the Hashed User ID"
msgstr "Basierend auf der gehashten Benutzer ID"
@ -1456,6 +1516,14 @@ msgstr ""
"Jeder Anbieter hat einen anderen Aussteller, der auf dem Slug der Anwendung "
"basiert."
#: authentik/providers/oauth2/models.py
msgid "Strict URL comparison"
msgstr "Strikter URL-Vergleich"
#: authentik/providers/oauth2/models.py
msgid "Regular Expression URL matching"
msgstr "Regex-URL-Vergleich"
#: authentik/providers/oauth2/models.py
msgid "code (Authorization Code Flow)"
msgstr "Code (Autorisierungsablauf)"
@ -1536,10 +1604,6 @@ msgstr "Client Geheimnis"
msgid "Redirect URIs"
msgstr "URIs weiterleiten"
#: authentik/providers/oauth2/models.py
msgid "Enter each URI on a new line."
msgstr "Geben Sie jeden URI in eine neue Zeile ein."
#: authentik/providers/oauth2/models.py
msgid "Include claims in id_token"
msgstr "Ansprüche in id_token berücksichtigen"
@ -1583,10 +1647,6 @@ msgstr ""
"Konfigurieren Sie, wie der Flow-Executor mit einer ungültigen Antwort auf "
"eine Abfrage umgehen soll."
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Signaturschlüssel"
#: authentik/providers/oauth2/models.py
msgid "Key used to sign the tokens."
msgstr "Schlüssel zum Signieren der Token."
@ -2094,6 +2154,10 @@ msgstr ""
"Benutzerdefinierte krb5.conf zur Benutzung. Benutzt standardmäßig die "
"systemeigene Konfiguration"
#: authentik/sources/kerberos/models.py
msgid "KAdmin server type"
msgstr "KAdmin-Servertyp"
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
msgstr "Synchronisiere Nutzer von Kerberos nach authentik"
@ -2340,7 +2404,7 @@ msgstr "Zugriffstoken-URL"
#: authentik/sources/oauth/models.py
msgid "URL used by authentik to retrieve tokens."
msgstr "URL, die von Authentik zum Abrufen von Token verwendet wird."
msgstr "URL, die von Authentik zum Abrufen von Tokens verwendet wird."
#: authentik/sources/oauth/models.py
msgid "Profile URL"
@ -3114,12 +3178,11 @@ msgstr ""
#, python-format
msgid ""
"\n"
" If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
" If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
" "
msgstr ""
"\n"
" Wenn Sie keine Passwortänderung beantragt haben, ignorieren Sie bitte diese E-Mail. Der obige Link ist gültig für %(expires)s.\n"
" "
"  Wenn Sie keine Passwortänderung beantragt haben, ignorieren Sie bitte diese E-Mail. Der obige Link ist gültig für %(expires)s."
#: authentik/stages/email/templates/email/password_reset.txt
#, python-format
@ -3138,7 +3201,7 @@ msgstr ""
#, python-format
msgid ""
"\n"
"If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
"If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
msgstr ""
"\n"
"Wenn Sie keine Passwortänderung beantragt haben, ignorieren Sie bitte diese E-Mail. Der obige Link ist gültig für %(expires)s.\n"
@ -3450,6 +3513,22 @@ msgstr "Aufforderungsstufen"
msgid "Passwords don't match."
msgstr "Passwörter stimmen nicht überein"
#: authentik/stages/redirect/api.py
msgid "Target URL should be present when mode is Static."
msgstr "Ziel-URL sollte beim statischen Modus vorhanden sein"
#: authentik/stages/redirect/api.py
msgid "Target Flow should be present when mode is Flow."
msgstr "Ziel-Flow sollte beim Flow-Modus vorhanden sein"
#: authentik/stages/redirect/models.py
msgid "Redirect Stage"
msgstr "Umleitungphase"
#: authentik/stages/redirect/models.py
msgid "Redirect Stages"
msgstr "Umleitungphasen"
#: authentik/stages/user_delete/models.py
msgid "User Delete Stage"
msgstr "Benutzer löschen Stufe"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-20 00:08+0000\n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -551,6 +551,47 @@ msgstr ""
msgid "(You are already connected in another tab/window)"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr ""
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr ""
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr ""
@ -826,7 +867,7 @@ msgid "Evaluate policies during the Flow planning process."
msgstr ""
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is present to the user."
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
#: authentik/flows/models.py
@ -1427,10 +1468,6 @@ msgstr ""
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr ""
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr ""
#: authentik/providers/oauth2/models.py
msgid "Key used to sign the tokens."
msgstr ""

Binary file not shown.

View File

@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-26 00:09+0000\n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Iamanaws, 2024\n"
"Language-Team: Spanish (https://app.transifex.com/authentik/teams/119923/es/)\n"
@ -116,6 +116,10 @@ msgstr "Marca"
msgid "Brands"
msgstr "Marcas"
#: authentik/core/api/application_entitlements.py
msgid "User does not have access to application."
msgstr ""
#: authentik/core/api/devices.py
msgid "Extra description not available"
msgstr "Descripción adicional no disponible."
@ -249,6 +253,14 @@ msgstr "Aplicación"
msgid "Applications"
msgstr "Aplicaciones"
#: authentik/core/models.py
msgid "Application Entitlement"
msgstr ""
#: authentik/core/models.py
msgid "Application Entitlements"
msgstr ""
#: authentik/core/models.py
msgid "Use the source-specific identifier"
msgstr "Usar el identificador específico de la fuente"
@ -592,6 +604,47 @@ msgstr "Límite máximo de conexiones alcanzado."
msgid "(You are already connected in another tab/window)"
msgstr "(Ya estás conectado en otra pestaña/ventana)"
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Clave de firma"
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr ""
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr ""
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr ""
@ -887,9 +940,8 @@ msgid "Evaluate policies during the Flow planning process."
msgstr "Evalúa políticas durante el proceso de planeación del Flujo."
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is present to the user."
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
"Evalúe las políticas cuando el escenario esté presente para el usuario."
#: authentik/flows/models.py
msgid ""
@ -1567,10 +1619,6 @@ msgstr ""
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr "Configure cómo se debe rellenar el campo emisor del token de ID."
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Clave de firma"
#: authentik/providers/oauth2/models.py
msgid "Key used to sign the tokens."
msgstr "Clave utilizada para firmar los tokens."
@ -2077,6 +2125,10 @@ msgstr "Dominio Kerberos"
msgid "Custom krb5.conf to use. Uses the system one by default"
msgstr "krb5.conf personalizado a usar. Usa el del sistema por defecto."
#: authentik/sources/kerberos/models.py
msgid "KAdmin server type"
msgstr ""
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
msgstr "Sincronizar usuarios desde Kerberos hacia Authentik"
@ -3099,12 +3151,9 @@ msgstr ""
#, python-format
msgid ""
"\n"
" If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
" If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
" "
msgstr ""
"\n"
" Si no solicitaste un cambio de contraseña, por favor ignora este correo. El enlace de arriba es valida por %(expires)s.\n"
" "
#: authentik/stages/email/templates/email/password_reset.txt
#, python-format
@ -3123,10 +3172,8 @@ msgstr ""
#, python-format
msgid ""
"\n"
"If you did not request a password change, please ignore this Email. The link above is valid for %(expires)s.\n"
"If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
msgstr ""
"\n"
"Si no solicitaste un cambio de contraseña, por favor ignora este correo. El enlace de arriba es valida por %(expires)s.\n"
#: authentik/stages/email/templates/email/setup.html
msgid "authentik Test-Email"
@ -3436,6 +3483,22 @@ msgstr "Etapas de Solicitud"
msgid "Passwords don't match."
msgstr "Las contraseñas no coinciden."
#: authentik/stages/redirect/api.py
msgid "Target URL should be present when mode is Static."
msgstr ""
#: authentik/stages/redirect/api.py
msgid "Target Flow should be present when mode is Flow."
msgstr ""
#: authentik/stages/redirect/models.py
msgid "Redirect Stage"
msgstr ""
#: authentik/stages/redirect/models.py
msgid "Redirect Stages"
msgstr ""
#: authentik/stages/user_delete/models.py
msgid "User Delete Stage"
msgstr "Etapa de eliminación del usuario"

Binary file not shown.

View File

@ -8,15 +8,16 @@
# Skyler Mäntysaari, 2024
# Jani Hast, 2024
# MarkoTukiainen, 2025
# Marc Schmitt, 2025
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-20 00:08+0000\n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: MarkoTukiainen, 2025\n"
"Last-Translator: Marc Schmitt, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/authentik/teams/119923/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -78,7 +79,7 @@ msgstr "Suunnitelman ilmentymät"
#: authentik/blueprints/v1/exporter.py
#, python-brace-format
msgid "authentik Export - {date}"
msgstr "authentik Vienti - {data}"
msgstr "authentik Vienti - {date}"
#: authentik/blueprints/v1/tasks.py authentik/crypto/tasks.py
#, python-brace-format
@ -594,6 +595,47 @@ msgstr "Yhteyksien enimmäismäärä saavutettu."
msgid "(You are already connected in another tab/window)"
msgstr "(Olet jo yhteydessä toisen selainvälilehden tai -ikkunan kautta)"
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Allekirjoitusavain"
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr ""
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr ""
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr ""
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr "Päätepisteen todentaja Google Device Trust Connector -vaihe"
@ -884,8 +926,8 @@ msgid "Evaluate policies during the Flow planning process."
msgstr "Suorita käytännöt prosessin suunnitteluvaiheen aikana."
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is present to the user."
msgstr "Suorita käytännöt kun vaihe näytetään käyttäjälle."
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
#: authentik/flows/models.py
msgid ""
@ -1559,10 +1601,6 @@ msgstr ""
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr "Määritä, miten myöntäjän ID-tunnisteen kenttä täytetään."
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Allekirjoitusavain"
#: authentik/providers/oauth2/models.py
msgid "Key used to sign the tokens."
msgstr "Avain, jota käytetään tunnisteiden allekirjoittamiseen."

Binary file not shown.

View File

@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-20 00:08+0000\n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Marc Schmitt, 2025\n"
"Language-Team: French (https://app.transifex.com/authentik/teams/119923/fr/)\n"
@ -608,6 +608,47 @@ msgstr "Limite maximum de connection atteinte."
msgid "(You are already connected in another tab/window)"
msgstr "(Vous êtes déjà connecté dans un autre onglet/une autre fenêtre)"
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Clé de signature"
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr "Clé utilisée pour signer les évènements SSF."
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr "Fournisseur Shared Signals Framework"
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr "Fournisseurs Shared Signals Framework"
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr "Ajouter un flux au fournisseur SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr "Flux SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr "Flux SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr "Évènement du flux SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr "Évènements du flux SSF"
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr "Échec de l'envoi de la requête"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr ""
@ -905,7 +946,7 @@ msgid "Evaluate policies during the Flow planning process."
msgstr "Évaluer les politiques durant la planification du flux."
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is present to the user."
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
"Évaluer les politiques lorsque l'étape est présentée est l'utilisateur."
@ -1585,10 +1626,6 @@ msgstr ""
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr "Configure comment le champ émetteur du jeton ID sera rempli."
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
msgstr "Clé de signature"
#: authentik/providers/oauth2/models.py
msgid "Key used to sign the tokens."
msgstr "Clé utilisée pour signer les jetons."

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