Compare commits

...

49 Commits

Author SHA1 Message Date
c8072579c8 release: 2024.4.0-rc1 2024-04-19 16:05:20 +02:00
378a701fb9 root: bump blueprint schema version
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 16:05:15 +02:00
bba793d94c lifecycle: fix ak test-all command
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 16:04:39 +02:00
53f8699deb website/docs: 2024.4 release notes (#9267)
* website/docs: 2024.4 release notes WIP

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

* fix .next

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

* reword

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

* add python api client

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

* fix consistency

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

* expand scim docs

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

* add release notes to sidebar

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

* update release notes and add disclaimer

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

* add disclaimer to template

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

* add list of API Clients to developer docs

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

* add performance improvements

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

* fix build

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 15:32:48 +02:00
6f3dc2eafd sources/ldap: fix default blueprint for mapping user DN to path (#9355)
* sources/ldap: fix default blueprint for mapping user DN to path

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

* fix tests

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 14:44:48 +02:00
567ed07fe8 web/admin: group form dual select (#9354)
* web/admin: migrate group form to dual-select

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

* unrelated: fix missing return in sidebar item non-link render

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 13:37:49 +02:00
2999e9d006 core: bump golang.org/x/net from 0.22.0 to 0.23.0 (#9351)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 13:00:27 +02:00
b32a228e3a core: bump goauthentik.io/api/v3 from 3.2024023.1 to 3.2024023.2 (#9345)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024023.1 to 3.2024023.2.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2024023.1...v3.2024023.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>
2024-04-19 12:26:30 +02:00
5a2dfb23c6 web: bump chromedriver from 123.0.3 to 123.0.4 in /tests/wdio (#9348)
Bumps [chromedriver](https://github.com/giggio/node-chromedriver) from 123.0.3 to 123.0.4.
- [Commits](https://github.com/giggio/node-chromedriver/compare/123.0.3...123.0.4)

---
updated-dependencies:
- dependency-name: chromedriver
  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>
2024-04-19 12:26:21 +02:00
8ebce479bd core: bump twilio from 9.0.4 to 9.0.5 (#9346)
Bumps [twilio](https://github.com/twilio/twilio-python) from 9.0.4 to 9.0.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.0.4...9.0.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>
2024-04-19 12:26:14 +02:00
81589e835e core: bump ruff from 0.3.7 to 0.4.0 (#9347)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.7 to 0.4.0.
- [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/v0.3.7...v0.4.0)

---
updated-dependencies:
- dependency-name: ruff
  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>
2024-04-19 12:26:06 +02:00
22b1f39b91 web: bump @sentry/browser from 7.110.1 to 7.111.0 in /web in the sentry group (#9349)
web: bump @sentry/browser in /web in the sentry group

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


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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 12:25:56 +02:00
c25e982f1f web/admin: fix user_write stage's user type input (#9344)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-19 01:07:24 +02:00
d5c09fae8a brands: add indexes to brand domain and default (#9343)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 23:10:17 +02:00
bf15e04053 web: fix locale prioritization scheme (#9341)
* web: fix esbuild issue with style sheets

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

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

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

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

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

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

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

* web: fix locale prioritization scheme

The locale priority algorithm had two problems: first, the order was incorrect, allowing the global
default from globalAK() to override a lot of more precise settings; second, the algorithm would take
outside locale overrides from the event handler, which was not necessary.

This commit revises the locale prioritization scheme.  It continues to watch for "change of locale"
events from all sources (URL, browser, and user/brand/site internal settings), but if the event
carries a suggested locale, that suggestion is ignored.  Instead, when a change of locale event
occurs, it re-runs the algorithm in priority order.

That order is:

- The URL query parameter `locale=`
- The User's stated preference in `CurrentUser.attributes`
- The Browser's stated locale
- The Brand's stated preference in `CurrentBrand.attributes`
- The authentik instance's setting `from window.globalAK()`
- The default locale complied into the UI at build time.

Note to @tanberry: We should note this order somewhere in the documentation, so that users are not
"surprised" that their user preference (set in User Interface -> Settings -> User Details -> Locale)
is not overriden by the browser's preference.  (The setting they need is "Based on your browser" to
make browser locale detection work.)

* web: fix locale prioritization scheme

The locale priority algorithm had two problems: first, the order was incorrect, allowing the global
default from globalAK() to override a lot of more precise settings; second, the algorithm would take
outside locale overrides from the event handler, which was not necessary.

This commit revises the locale prioritization scheme.  It continues to watch for "change of locale"
events from all sources (URL, browser, and user/brand/site internal settings), but if the event
carries a suggested locale, that suggestion is ignored.  Instead, when a change of locale event
occurs, it re-runs the algorithm in priority order.

That order is:

- The URL query parameter `locale=`
- The User's stated preference in `CurrentUser.attributes`
- The Browser's stated locale
- The Brand's stated preference in `CurrentBrand.attributes`
- The authentik instance's setting `from window.globalAK()`
- The default locale complied into the UI at build time.

Note to @tanberry: We should note this order somewhere in the documentation, so that users are not
"surprised" that their user preference (set in User Interface -> Settings -> User Details -> Locale)
is not overriden by the browser's preference.  (The setting they need is "Based on your browser" to
make browser locale detection work.)

* web: locale patch for currentUser.settings

Temporarily skipping currentUser.settings.locale as a source of
truth because it's not portable between User/Admin and Flow; Flow
in a logged-out state has no access to `/me`, but we need to probe
`/me` for user settings.  This conflict currently triggers a bug
in the session heartbeat handler.
2024-04-18 22:41:32 +02:00
0932622567 core: bump aiohttp from 3.9.2 to 3.9.4 (#9339)
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.2 to 3.9.4.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.2...v3.9.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-18 20:55:59 +02:00
0a5b8bea5d stages/prompt: fix username field throwing error with existing user (#9342)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 20:54:31 +02:00
64d4a19ccf root: expose session storage configuration (#9337)
* root: expose session storage configuration

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>
2024-04-18 20:53:27 +02:00
82875cfc0e website/integrations: fix typo (#9340)
Update index.md to fix typo

Changed typo "thread model" to, "threat model."

Signed-off-by: Code Dreams <59837770+Code-Dreams@users.noreply.github.com>
2024-04-18 20:23:55 +02:00
83776b9f08 root: fix go.mod for codeql checking (#9338)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 17:48:49 +02:00
a742331484 root: make redis settings more consistent (#9335)
* make redis settings more consistent

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

* add support to go

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

* rewrite url

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

* fix redis connect in wait_for_db

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

* censor password when logging error

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

* update docs

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

* reword docs

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

* add redis url generation helper

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 16:49:41 +02:00
2e9df96a62 web/admin: fix error in admin interface due to un-hydrated context (#9336)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 16:49:17 +02:00
9f5d7089c3 web: bump API Client version (#9334)
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>
2024-04-18 14:03:00 +02:00
ddc78cc297 stages/authenticator_webauthn: fix attestation value (#9333)
* fix incorrect attestation conveyance with device restriction

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

* save raw aaguid on webauthn device

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 14:00:16 +02:00
cb9b3407d8 website/docs: fix SECRET_KEY length (#9328)
Django complains about 36-character keys. See security.W009 on
https://docs.djangoproject.com/en/5.0/ref/checks/.
2024-04-18 12:20:30 +02:00
d7b872c1e0 website/docs: fix email template formatting (#9330)
fix formating issue

Fixes:
django.template.exceptions.TemplateSyntaxError: 'blocktrans' doesn't allow other block tags (seen "trans 'You recently requested to change your password for you authentik account. Use the button below to set a new password.'") inside it

Signed-off-by: Zapfmeister <zapfmeister@gmail.com>
2024-04-18 12:20:17 +02:00
c35217f581 core, web: update translations (#9323)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-04-18 11:59:45 +02:00
3b73a2eb9d web: bump @patternfly/elements from 3.0.0 to 3.0.1 in /web (#9324)
Bumps [@patternfly/elements](https://github.com/patternfly/patternfly-elements/tree/HEAD/elements) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/patternfly/patternfly-elements/releases)
- [Changelog](https://github.com/patternfly/patternfly-elements/blob/main/elements/CHANGELOG.md)
- [Commits](https://github.com/patternfly/patternfly-elements/commits/@patternfly/elements@3.0.1/elements)

---
updated-dependencies:
- dependency-name: "@patternfly/elements"
  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>
2024-04-18 11:59:27 +02:00
3b94ffa705 core: bump celery from 5.3.6 to 5.4.0 (#9325)
Bumps [celery](https://github.com/celery/celery) from 5.3.6 to 5.4.0.
- [Release notes](https://github.com/celery/celery/releases)
- [Changelog](https://github.com/celery/celery/blob/main/Changelog.rst)
- [Commits](https://github.com/celery/celery/compare/v5.3.6...v5.4.0)

---
updated-dependencies:
- dependency-name: celery
  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>
2024-04-18 11:58:12 +02:00
936102f6d9 core: bump goauthentik.io/api/v3 from 3.2024022.12 to 3.2024023.1 (#9327)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024022.12 to 3.2024023.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2024022.12...v3.2024023.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>
2024-04-18 11:58:02 +02:00
8c687d81aa sources/scim: service account should be internal (#9321)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-18 01:53:26 +02:00
01d7263484 web: bump the storybook group in /web with 8 updates (#9266)
Bumps the storybook group in /web with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/essentials) | `7.6.17` | `8.0.8` |
| [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links) | `7.6.17` | `8.0.8` |
| [@storybook/blocks](https://github.com/storybookjs/storybook/tree/HEAD/code/ui/blocks) | `7.6.17` | `8.0.8` |
| [@storybook/manager-api](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/manager-api) | `7.6.17` | `8.0.8` |
| [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) | `7.6.17` | `8.0.8` |
| [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite) | `7.6.17` | `8.0.8` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/cli) | `7.6.17` | `8.0.8` |
| [storybook-addon-mock](https://github.com/nutboltu/storybook-addon-mock) | `4.3.0` | `5.0.0` |


Updates `@storybook/addon-essentials` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/addons/essentials)

Updates `@storybook/addon-links` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/addons/links)

Updates `@storybook/blocks` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/ui/blocks)

Updates `@storybook/manager-api` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/lib/manager-api)

Updates `@storybook/web-components` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/frameworks/web-components-vite)

Updates `storybook` from 7.6.17 to 8.0.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.0.8/code/lib/cli)

Updates `storybook-addon-mock` from 4.3.0 to 5.0.0
- [Release notes](https://github.com/nutboltu/storybook-addon-mock/releases)
- [Commits](https://github.com/nutboltu/storybook-addon-mock/compare/4.3.0...5.0.0)

---
updated-dependencies:
- dependency-name: "@storybook/addon-essentials"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/blocks"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/manager-api"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: storybook
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: storybook-addon-mock
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: storybook
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-17 22:57:27 +02:00
49ac0eb662 sources/scim: cleanup service account when source is deleted (#9319)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-17 22:57:05 +02:00
8935ca65a7 web: bump API Client version (#9316)
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>
2024-04-17 13:35:44 +00:00
58a374d1f1 release: 2024.2.3
Signed-off-by: Jens Langhammer <jens@goauthentik.io>

# Conflicts:
#	pyproject.toml
2024-04-17 15:17:14 +02:00
f409831921 website/docs: 2024.2.3 release notes (#9313)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-17 13:17:49 +02:00
951acb26dd web/admin: fix log viewer empty state (#9315)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-17 13:13:03 +02:00
2df0c95806 website/docs: fix formatting for stage changes (#9314)
fix formatting for stages

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-17 13:12:53 +02:00
f8d1b7b9b7 core: bump github.com/go-ldap/ldap/v3 from 3.4.7 to 3.4.8 (#9310)
Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.4.7 to 3.4.8.
- [Release notes](https://github.com/go-ldap/ldap/releases)
- [Commits](https://github.com/go-ldap/ldap/compare/v3.4.7...v3.4.8)

---
updated-dependencies:
- dependency-name: github.com/go-ldap/ldap/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>
2024-04-17 12:09:59 +02:00
e092aabb21 core: bump goauthentik.io/api/v3 from 3.2024022.11 to 3.2024022.12 (#9311)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024022.11 to 3.2024022.12.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2024022.11...v3.2024022.12)

---
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>
2024-04-17 12:09:46 +02:00
48c59a815d web: bump core-js from 3.36.1 to 3.37.0 in /web (#9309)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.36.1 to 3.37.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.37.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  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>
2024-04-17 12:09:25 +02:00
9f40716a87 core: bump gunicorn from 21.2.0 to 22.0.0 (#9308)
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 21.2.0 to 22.0.0.
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](https://github.com/benoitc/gunicorn/compare/21.2.0...22.0.0)

---
updated-dependencies:
- dependency-name: gunicorn
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-17 12:08:21 +02:00
39da241298 core, web: update translations (#9307)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-04-17 12:08:08 +02:00
a71a87fa3e website/docs: system settings: add default token duration and length (#9306) 2024-04-16 23:16:58 +00:00
176fe2f6fc web/flows: update flow background (#9305)
* web/flows: update flow background

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

* Optimised images with calibre/image-actions

* I changed my mind

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

* manually shrink

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2024-04-17 00:44:32 +02:00
4544f475c9 web: fix locale loading being skipped (#9301)
Fix locale loading being skipped.

Co-authored-by: Dylan Kauling <dkauling@armstrongfluidtechnology.com>
2024-04-17 00:35:35 +02:00
5bbf59b2bd translate: Updates for file web/xliff/en.xlf in fr (#9304)
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>
2024-04-16 22:35:02 +00:00
1b2f1db711 translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#9303)
* Translate locale/en/LC_MESSAGES/django.po in fr

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

* 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>
2024-04-16 22:27:05 +00:00
14fab991b4 core: replace authentik_signals_ignored_fields with audit_ignore (#9291)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-04-17 00:19:18 +02:00
92 changed files with 4087 additions and 2571 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.2.2
current_version = 2024.4.0-rc1
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?
@ -21,6 +21,8 @@ optional_value = final
[bumpversion:file:schema.yml]
[bumpversion:file:blueprints/schema.json]
[bumpversion:file:authentik/__init__.py]
[bumpversion:file:internal/constants/constants.go]

View File

@ -18,10 +18,10 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
(.x being the latest patch release for each version)
| Version | Supported |
| --- | --- |
| 2023.6.x | ✅ |
| 2023.8.x | ✅ |
| Version | Supported |
| --------- | --------- |
| 2023.10.x | ✅ |
| 2024.2.x | ✅ |
## Reporting a Vulnerability
@ -31,12 +31,12 @@ To report a vulnerability, send an email to [security@goauthentik.io](mailto:se
authentik reserves the right to reclassify CVSS as necessary. To determine severity, we will use the CVSS calculator from NVD (https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator). The calculated CVSS score will then be translated into one of the following categories:
| Score | Severity |
| --- | --- |
| 0.0 | None |
| 0.1 3.9 | Low |
| 4.0 6.9 | Medium |
| 7.0 8.9 | High |
| Score | Severity |
| ---------- | -------- |
| 0.0 | None |
| 0.1 3.9 | Low |
| 4.0 6.9 | Medium |
| 7.0 8.9 | High |
| 9.0 10.0 | Critical |
## Disclosure process

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2024.2.2"
__version__ = "2024.4.0"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -0,0 +1,21 @@
# Generated by Django 5.0.4 on 2024-04-18 18:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_brands", "0005_tenantuuid_to_branduuid"),
]
operations = [
migrations.AddIndex(
model_name="brand",
index=models.Index(fields=["domain"], name="authentik_b_domain_b9b24a_idx"),
),
migrations.AddIndex(
model_name="brand",
index=models.Index(fields=["default"], name="authentik_b_default_3ccf12_idx"),
),
]

View File

@ -84,3 +84,7 @@ class Brand(SerializerModel):
class Meta:
verbose_name = _("Brand")
verbose_name_plural = _("Brands")
indexes = [
models.Index(fields=["domain"]),
models.Index(fields=["default"]),
]

View File

@ -54,9 +54,6 @@ options.DEFAULT_NAMES = options.DEFAULT_NAMES + (
# used_by API that allows models to specify if they shadow an object
# for example the proxy provider which is built on top of an oauth provider
"authentik_used_by_shadows",
# List fields for which changes are not logged (due to them having dedicated objects)
# for example user's password and last_login
"authentik_signals_ignored_fields",
)
@ -335,14 +332,6 @@ class User(SerializerModel, GuardianUserMixin, AbstractUser):
models.Index(fields=["path"]),
models.Index(fields=["type"]),
]
authentik_signals_ignored_fields = [
# Logged by the events `password_set`
# the `password_set` action/signal doesn't currently convey which user
# initiated the password change, so for now we'll log two actions
# ("password", "password_change_date"),
# Logged by `login`
("last_login",),
]
class Provider(SerializerModel):

View File

@ -102,9 +102,4 @@ class EnterpriseAuditMiddleware(AuditMiddleware):
new_state = self.serialize_simple(instance)
diff = self.diff(prev_state, new_state)
thread_kwargs["diff"] = diff
if not created:
ignored_field_sets = getattr(instance._meta, "authentik_signals_ignored_fields", [])
for field_set in ignored_field_sets:
if set(diff.keys()) == set(field_set):
return None
return super().post_save_handler(request, sender, instance, created, thread_kwargs, **_)

View File

@ -14,7 +14,7 @@ from pathlib import Path
from sys import argv, stderr
from time import time
from typing import Any
from urllib.parse import urlparse
from urllib.parse import quote_plus, urlparse
import yaml
from django.conf import ImproperlyConfigured
@ -331,6 +331,26 @@ class ConfigLoader:
CONFIG = ConfigLoader()
def redis_url(db: int) -> str:
"""Helper to create a Redis URL for a specific database"""
_redis_protocol_prefix = "redis://"
_redis_tls_requirements = ""
if CONFIG.get_bool("redis.tls", False):
_redis_protocol_prefix = "rediss://"
_redis_tls_requirements = f"?ssl_cert_reqs={CONFIG.get('redis.tls_reqs')}"
if _redis_ca := CONFIG.get("redis.tls_ca_cert", None):
_redis_tls_requirements += f"&ssl_ca_certs={_redis_ca}"
_redis_url = (
f"{_redis_protocol_prefix}"
f"{quote_plus(CONFIG.get('redis.username'))}:"
f"{quote_plus(CONFIG.get('redis.password'))}@"
f"{quote_plus(CONFIG.get('redis.host'))}:"
f"{CONFIG.get_int('redis.port')}"
f"/{db}{_redis_tls_requirements}"
)
return _redis_url
if __name__ == "__main__":
if len(argv) < 2: # noqa: PLR2004
print(dumps(CONFIG.raw, indent=4, cls=AttrEncoder))

View File

@ -35,6 +35,7 @@ redis:
password: ""
tls: false
tls_reqs: "none"
tls_ca_cert: null
# broker:
# url: ""
@ -58,6 +59,8 @@ remote_debug: false
log_level: info
session_storage: cache
error_reporting:
enabled: false
sentry_dsn: https://151ba72610234c4c97c5bcff4e1cffd8@authentik.error-reporting.a7k.io/4504163677503489

View File

@ -5,13 +5,13 @@ import os
from collections import OrderedDict
from hashlib import sha512
from pathlib import Path
from urllib.parse import quote_plus
from celery.schedules import crontab
from django.conf import ImproperlyConfigured
from sentry_sdk import set_tag
from authentik import ENV_GIT_HASH_KEY, __version__
from authentik.lib.config import CONFIG
from authentik.lib.config import CONFIG, redis_url
from authentik.lib.logging import get_logger_config, structlog_configure
from authentik.lib.sentry import sentry_init
from authentik.lib.utils.reflection import get_env
@ -195,25 +195,15 @@ REST_FRAMEWORK = {
},
}
_redis_protocol_prefix = "redis://"
_redis_celery_tls_requirements = ""
if CONFIG.get_bool("redis.tls", False):
_redis_protocol_prefix = "rediss://"
_redis_celery_tls_requirements = f"?ssl_cert_reqs={CONFIG.get('redis.tls_reqs')}"
_redis_url = (
f"{_redis_protocol_prefix}"
f"{quote_plus(CONFIG.get('redis.username'))}:"
f"{quote_plus(CONFIG.get('redis.password'))}@"
f"{quote_plus(CONFIG.get('redis.host'))}:"
f"{CONFIG.get_int('redis.port')}"
)
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": CONFIG.get("cache.url") or f"{_redis_url}/{CONFIG.get('redis.db')}",
"LOCATION": CONFIG.get("cache.url") or redis_url(CONFIG.get("redis.db")),
"TIMEOUT": CONFIG.get_int("cache.timeout", 300),
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
"KEY_PREFIX": "authentik_cache",
"KEY_FUNCTION": "django_tenants.cache.make_key",
"REVERSE_KEY_FUNCTION": "django_tenants.cache.reverse_key",
@ -222,7 +212,15 @@ CACHES = {
DJANGO_REDIS_SCAN_ITERSIZE = 1000
DJANGO_REDIS_IGNORE_EXCEPTIONS = True
DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
match CONFIG.get("session_storage", "cache"):
case "cache":
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
case "db":
SESSION_ENGINE = "django.contrib.sessions.backends.db"
case _:
raise ImproperlyConfigured(
"Invalid session_storage setting, allowed values are db and cache"
)
SESSION_SERIALIZER = "authentik.root.sessions.pickle.PickleSerializer"
SESSION_CACHE_ALIAS = "default"
# Configured via custom SessionMiddleware
@ -276,7 +274,7 @@ CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer",
"CONFIG": {
"hosts": [CONFIG.get("channel.url", f"{_redis_url}/{CONFIG.get('redis.db')}")],
"hosts": [CONFIG.get("channel.url") or redis_url(CONFIG.get("redis.db"))],
"prefix": "authentik_channels_",
},
},
@ -376,11 +374,9 @@ CELERY = {
"beat_scheduler": "authentik.tenants.scheduler:TenantAwarePersistentScheduler",
"task_create_missing_queues": True,
"task_default_queue": "authentik",
"broker_url": CONFIG.get("broker.url")
or f"{_redis_url}/{CONFIG.get('redis.db')}{_redis_celery_tls_requirements}",
"broker_url": CONFIG.get("broker.url") or redis_url(CONFIG.get("redis.db")),
"result_backend": CONFIG.get("result_backend.url") or redis_url(CONFIG.get("redis.db")),
"broker_transport_options": CONFIG.get_dict_from_b64_json("broker.transport_options"),
"result_backend": CONFIG.get("result_backend.url")
or f"{_redis_url}/{CONFIG.get('redis.db')}{_redis_celery_tls_requirements}",
}
# Sentry integration

View File

@ -34,7 +34,7 @@ def mock_ad_connection(password: str) -> Connection:
"objectSid": "unique-test-group",
"objectClass": "group",
"distinguishedName": "cn=group1,ou=groups,dc=goauthentik,dc=io",
"member": ["cn=user0,ou=users,dc=goauthentik,dc=io"],
"member": ["cn=user,ou=users,dc=goauthentik,dc=io"],
},
)
# Group without SID
@ -47,7 +47,7 @@ def mock_ad_connection(password: str) -> Connection:
},
)
connection.strategy.add_entry(
"cn=user0,ou=users,dc=goauthentik,dc=io",
"cn=user0,ou=foo,ou=users,dc=goauthentik,dc=io",
{
"userPassword": password,
"sAMAccountName": "user0_sn",

View File

@ -55,7 +55,7 @@ class LDAPSyncTests(TestCase):
)
connection.assert_called_with(
connection_kwargs={
"user": "cn=user0,ou=users,dc=goauthentik,dc=io",
"user": "cn=user0,ou=foo,ou=users,dc=goauthentik,dc=io",
"password": LDAP_PASSWORD,
}
)

View File

@ -7,7 +7,6 @@ from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import SourceSerializer
from authentik.core.api.tokens import TokenSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.models import Token, TokenIntents, User, UserTypes
from authentik.sources.scim.models import SCIMSource
@ -27,25 +26,6 @@ class SCIMSourceSerializer(SourceSerializer):
return relative_url
return self.context["request"].build_absolute_uri(relative_url)
def create(self, validated_data):
instance: SCIMSource = super().create(validated_data)
identifier = f"ak-source-scim-{instance.pk}"
user = User.objects.create(
username=identifier,
name=f"SCIM Source {instance.name} Service-Account",
type=UserTypes.SERVICE_ACCOUNT,
)
token = Token.objects.create(
user=user,
identifier=identifier,
intent=TokenIntents.INTENT_API,
expiring=False,
managed=f"goauthentik.io/sources/scim/{instance.pk}",
)
instance.token = token
instance.save()
return instance
class Meta:
model = SCIMSource

View File

@ -1,12 +1,13 @@
"""Authentik SCIM app config"""
from django.apps import AppConfig
from authentik.blueprints.apps import ManagedAppConfig
class AuthentikSourceSCIMConfig(AppConfig):
class AuthentikSourceSCIMConfig(ManagedAppConfig):
"""authentik SCIM Source app config"""
name = "authentik.sources.scim"
label = "authentik_sources_scim"
verbose_name = "authentik Sources.SCIM"
mountpoint = "source/scim/"
default = True

View File

@ -1,5 +1,7 @@
"""SCIM Source"""
from uuid import uuid4
from django.db import models
from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import BaseSerializer
@ -14,6 +16,12 @@ class SCIMSource(Source):
token = models.ForeignKey(Token, on_delete=models.CASCADE, null=True, default=None)
@property
def service_account_identifier(self) -> str:
if not self.pk:
self.pk = uuid4()
return f"ak-source-scim-{self.pk}"
@property
def component(self) -> str:
"""Return component used to edit this object"""

View File

@ -0,0 +1,38 @@
from django.db.models import Model
from django.db.models.signals import pre_delete, pre_save
from django.dispatch import receiver
from authentik.core.models import Token, TokenIntents, User, UserTypes
from authentik.sources.scim.models import SCIMSource
@receiver(pre_save, sender=SCIMSource)
def scim_source_pre_save(sender: type[Model], instance: SCIMSource, **_):
"""Create service account before source is saved"""
# .service_account_identifier will auto-assign a primary key uuid to the source
# if none is set yet, just so we can get the identifier before we save
identifier = instance.service_account_identifier
user = User.objects.create(
username=identifier,
name=f"SCIM Source {instance.name} Service-Account",
type=UserTypes.INTERNAL_SERVICE_ACCOUNT,
)
token = Token.objects.create(
user=user,
identifier=identifier,
intent=TokenIntents.INTENT_API,
expiring=False,
managed=f"goauthentik.io/sources/scim/{instance.pk}",
)
instance.token = token
@receiver(pre_delete, sender=SCIMSource)
def scim_source_pre_delete(sender: type[Model], instance: SCIMSource, **_):
"""Delete SCIM Source service account before deleting source"""
Token.objects.filter(
identifier=instance.service_account_identifier, intent=TokenIntents.INTENT_API
).delete()
User.objects.filter(
username=instance.service_account_identifier, type=UserTypes.INTERNAL_SERVICE_ACCOUNT
).delete()

View File

@ -14,27 +14,13 @@ class TestSCIMAuth(APITestCase):
def setUp(self) -> None:
self.user = create_test_admin_user()
self.token = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.token2 = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.token3 = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.source = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token
)
self.source2 = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token2
)
self.source = SCIMSource.objects.create(name=generate_id(), slug=generate_id())
self.source2 = SCIMSource.objects.create(name=generate_id(), slug=generate_id())
def test_auth_ok(self):
"""Test successful auth"""
@ -45,7 +31,7 @@ class TestSCIMAuth(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
@ -71,7 +57,7 @@ class TestSCIMAuth(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token2.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source2.token.key}",
)
self.assertEqual(response.status_code, 403)
# Token for no source

View File

@ -3,8 +3,6 @@
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Token, TokenIntents
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id
from authentik.sources.scim.models import SCIMSource
@ -13,14 +11,9 @@ class TestSCIMResourceTypes(APITestCase):
"""Test SCIM ResourceTypes view"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.token = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.source = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token
name=generate_id(),
slug=generate_id(),
)
def test_resource_type(self):
@ -32,7 +25,7 @@ class TestSCIMResourceTypes(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
@ -46,7 +39,7 @@ class TestSCIMResourceTypes(APITestCase):
"resource_type": "ServiceProviderConfig",
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
@ -60,6 +53,6 @@ class TestSCIMResourceTypes(APITestCase):
"resource_type": "foo",
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 404)

View File

@ -3,8 +3,6 @@
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Token, TokenIntents
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id
from authentik.sources.scim.models import SCIMSource
@ -13,15 +11,7 @@ class TestSCIMSchemas(APITestCase):
"""Test SCIM Schema view"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.token = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.source = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token
)
self.source = SCIMSource.objects.create(name=generate_id(), slug=generate_id())
def test_schema(self):
"""Test full schema view"""
@ -32,7 +22,7 @@ class TestSCIMSchemas(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
@ -46,7 +36,7 @@ class TestSCIMSchemas(APITestCase):
"schema_uri": "urn:ietf:params:scim:schemas:core:2.0:Meta",
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
@ -60,6 +50,6 @@ class TestSCIMSchemas(APITestCase):
"schema_uri": "foo",
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 404)

View File

@ -3,8 +3,6 @@
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Token, TokenIntents
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id
from authentik.sources.scim.models import SCIMSource
@ -13,14 +11,9 @@ class TestSCIMServiceProviderConfig(APITestCase):
"""Test SCIM ServiceProviderConfig view"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.token = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.source = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token
name=generate_id(),
slug=generate_id(),
)
def test_config(self):
@ -32,6 +25,6 @@ class TestSCIMServiceProviderConfig(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)

View File

@ -0,0 +1,27 @@
"""Test SCIM Source creation"""
from rest_framework.test import APITestCase
from authentik.core.models import Token, User
from authentik.lib.generators import generate_id
from authentik.sources.scim.models import SCIMSource
class TestSCIMSignals(APITestCase):
"""Test SCIM Signals view"""
def setUp(self) -> None:
self.uid = generate_id()
def test_create(self) -> None:
source = SCIMSource.objects.create(name=self.uid, slug=self.uid)
self.assertIsNotNone(source.token)
self.assertIsNotNone(source.token.user)
def test_delete(self):
self.test_create()
source = SCIMSource.objects.filter(slug=self.uid).first()
identifier = source.service_account_identifier
source.delete()
self.assertFalse(User.objects.filter(username=identifier).exists())
self.assertFalse(Token.objects.filter(identifier=identifier).exists())

View File

@ -6,8 +6,8 @@ from uuid import uuid4
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Token, TokenIntents
from authentik.core.tests.utils import create_test_admin_user
from authentik.core.tests.utils import create_test_user
from authentik.events.models import Event, EventAction
from authentik.lib.generators import generate_id
from authentik.providers.scim.clients.schema import User as SCIMUserSchema
from authentik.sources.scim.models import SCIMSource, SCIMSourceUser
@ -18,15 +18,7 @@ class TestSCIMUsers(APITestCase):
"""Test SCIM User view"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.token = Token.objects.create(
user=self.user,
identifier=generate_id(),
intent=TokenIntents.INTENT_API,
)
self.source = SCIMSource.objects.create(
name=generate_id(), slug=generate_id(), token=self.token
)
self.source = SCIMSource.objects.create(name=generate_id(), slug=generate_id())
def test_user_list(self):
"""Test full user list"""
@ -37,15 +29,16 @@ class TestSCIMUsers(APITestCase):
"source_slug": self.source.slug,
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
def test_user_list_single(self):
"""Test full user list (single user)"""
user = create_test_user()
SCIMSourceUser.objects.create(
source=self.source,
user=self.user,
user=user,
id=str(uuid4()),
)
response = self.client.get(
@ -53,16 +46,17 @@ class TestSCIMUsers(APITestCase):
"authentik_sources_scim:v2-users",
kwargs={
"source_slug": self.source.slug,
"user_id": str(self.user.uuid),
"user_id": str(user.uuid),
},
),
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 200)
SCIMUserSchema.model_validate_json(response.content, strict=True)
def test_user_create(self):
"""Test user create"""
user = create_test_user()
ext_id = generate_id()
response = self.client.post(
reverse(
@ -78,13 +72,18 @@ class TestSCIMUsers(APITestCase):
"emails": [
{
"primary": True,
"value": self.user.email,
"value": user.email,
}
],
}
),
content_type=SCIM_CONTENT_TYPE,
HTTP_AUTHORIZATION=f"Bearer {self.token.key}",
HTTP_AUTHORIZATION=f"Bearer {self.source.token.key}",
)
self.assertEqual(response.status_code, 201)
self.assertTrue(SCIMSourceUser.objects.filter(source=self.source, id=ext_id).exists())
self.assertTrue(
Event.objects.filter(
action=EventAction.MODEL_CREATED, user__username=self.source.token.user.username
).exists()
)

View File

@ -20,7 +20,10 @@ class WebAuthnDeviceSerializer(ModelSerializer):
class Meta:
model = WebAuthnDevice
fields = ["pk", "name", "created_on", "device_type"]
fields = ["pk", "name", "created_on", "device_type", "aaguid"]
extra_kwargs = {
"aaguid": {"read_only": True},
}
class WebAuthnDeviceViewSet(

View File

@ -0,0 +1,168 @@
# Generated by Django 5.0.4 on 2024-04-18 11:29
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
replaces = [
("authentik_stages_authenticator_webauthn", "0001_initial"),
("authentik_stages_authenticator_webauthn", "0002_default_setup_flow"),
("authentik_stages_authenticator_webauthn", "0003_webauthndevice_confirmed"),
("authentik_stages_authenticator_webauthn", "0004_auto_20210304_1850"),
(
"authentik_stages_authenticator_webauthn",
"0005_authenticatewebauthnstage_user_verification",
),
(
"authentik_stages_authenticator_webauthn",
"0006_authenticatewebauthnstage_authenticator_attachment_and_more",
),
(
"authentik_stages_authenticator_webauthn",
"0007_rename_last_used_on_webauthndevice_last_t",
),
("authentik_stages_authenticator_webauthn", "0008_alter_webauthndevice_credential_id"),
("authentik_stages_authenticator_webauthn", "0009_authenticatewebauthnstage_friendly_name"),
(
"authentik_stages_authenticator_webauthn",
"0010_webauthndevicetype_authenticatorwebauthnstage_and_more",
),
("authentik_stages_authenticator_webauthn", "0011_webauthndevice_aaguid"),
]
initial = True
dependencies = [
("authentik_flows", "0016_auto_20201202_1307"),
("authentik_flows", "0027_auto_20231028_1424"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="WebAuthnDeviceType",
fields=[
("aaguid", models.UUIDField(primary_key=True, serialize=False, unique=True)),
("description", models.TextField()),
("icon", models.TextField(null=True)),
],
options={
"verbose_name": "WebAuthn Device type",
"verbose_name_plural": "WebAuthn Device types",
},
),
migrations.CreateModel(
name="AuthenticatorWebAuthnStage",
fields=[
(
"stage_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_flows.stage",
),
),
(
"configure_flow",
models.ForeignKey(
blank=True,
help_text="Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="authentik_flows.flow",
),
),
(
"user_verification",
models.TextField(
choices=[
("required", "Required"),
("preferred", "Preferred"),
("discouraged", "Discouraged"),
],
default="preferred",
),
),
(
"authenticator_attachment",
models.TextField(
choices=[("platform", "Platform"), ("cross-platform", "Cross Platform")],
default=None,
null=True,
),
),
(
"resident_key_requirement",
models.TextField(
choices=[
("discouraged", "Discouraged"),
("preferred", "Preferred"),
("required", "Required"),
],
default="preferred",
),
),
("friendly_name", models.TextField(null=True)),
(
"device_type_restrictions",
models.ManyToManyField(
blank=True, to="authentik_stages_authenticator_webauthn.webauthndevicetype"
),
),
],
options={
"verbose_name": "WebAuthn Authenticator Setup Stage",
"verbose_name_plural": "WebAuthn Authenticator Setup Stages",
},
bases=("authentik_flows.stage", models.Model),
),
migrations.CreateModel(
name="WebAuthnDevice",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.TextField(max_length=200)),
("credential_id", models.TextField(unique=True)),
("public_key", models.TextField()),
("sign_count", models.IntegerField(default=0)),
("rp_id", models.CharField(max_length=253)),
("created_on", models.DateTimeField(auto_now_add=True)),
("last_t", models.DateTimeField(default=django.utils.timezone.now)),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
(
"confirmed",
models.BooleanField(default=True, help_text="Is this device ready for use?"),
),
(
"device_type",
models.ForeignKey(
default=None,
null=True,
on_delete=django.db.models.deletion.SET_DEFAULT,
to="authentik_stages_authenticator_webauthn.webauthndevicetype",
),
),
("aaguid", models.TextField(default="00000000-0000-0000-0000-000000000000")),
],
options={
"verbose_name": "WebAuthn Device",
"verbose_name_plural": "WebAuthn Devices",
},
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 5.0.4 on 2024-04-18 11:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
(
"authentik_stages_authenticator_webauthn",
"0010_webauthndevicetype_authenticatorwebauthnstage_and_more",
),
]
operations = [
migrations.AddField(
model_name="webauthndevice",
name="aaguid",
field=models.TextField(default="00000000-0000-0000-0000-000000000000"),
),
]

View File

@ -132,6 +132,7 @@ class WebAuthnDevice(SerializerModel, Device):
created_on = models.DateTimeField(auto_now_add=True)
last_t = models.DateTimeField(default=now)
aaguid = models.TextField(default=UNKNOWN_DEVICE_TYPE_AAGUID)
device_type = models.ForeignKey(
"WebAuthnDeviceType", on_delete=models.SET_DEFAULT, null=True, default=None
)

View File

@ -126,10 +126,6 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
if authenticator_attachment:
authenticator_attachment = AuthenticatorAttachment(str(authenticator_attachment))
attestation = AttestationConveyancePreference.DIRECT
if stage.device_type_restrictions.exists():
attestation = AttestationConveyancePreference.ENTERPRISE
registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
rp_id=get_rp_id(self.request),
rp_name=self.request.brand.branding_title,
@ -141,7 +137,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
user_verification=UserVerificationRequirement(str(stage.user_verification)),
authenticator_attachment=authenticator_attachment,
),
attestation=attestation,
attestation=AttestationConveyancePreference.DIRECT,
)
self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = registration_options.challenge
@ -180,6 +176,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
sign_count=webauthn_credential.sign_count,
rp_id=get_rp_id(self.request),
device_type=device_type,
aaguid=webauthn_credential.aaguid,
)
else:
return self.executor.stage_invalid("Device with Credential ID already exists.")

View File

@ -150,22 +150,26 @@ class PromptChallengeResponse(ChallengeResponse):
return attrs
def username_field_validator_factory() -> Callable[[PromptChallenge, str], Any]:
def username_field_validator_factory() -> Callable[[PromptChallengeResponse, str], Any]:
"""Return a `clean_` method for `field`. Clean method checks if username is taken already."""
def username_field_validator(_: PromptChallenge, value: str) -> Any:
def username_field_validator(self: PromptChallengeResponse, value: str) -> Any:
"""Check for duplicate usernames"""
if User.objects.filter(username=value).exists():
pending_user = self.stage.get_pending_user()
query = User.objects.all()
if pending_user.pk:
query = query.exclude(username=pending_user.username)
if query.filter(username=value).exists():
raise ValidationError("Username is already taken.")
return value
return username_field_validator
def password_single_validator_factory() -> Callable[[PromptChallenge, str], Any]:
def password_single_validator_factory() -> Callable[[PromptChallengeResponse, str], Any]:
"""Return a `clean_` method for `field`. Clean method checks if username is taken already."""
def password_single_clean(self: PromptChallenge, value: str) -> Any:
def password_single_clean(self: PromptChallengeResponse, value: str) -> Any:
"""Send password validation signals for e.g. LDAP Source"""
password_validate.send(sender=self, password=value, plan_context=self.plan.context)
return value

View File

@ -9,6 +9,7 @@ from django.utils.translation import gettext as _
from rest_framework.fields import BooleanField, CharField
from authentik.core.models import AuthenticatedSession, User
from authentik.events.middleware import audit_ignore
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE
from authentik.flows.stage import ChallengeStageView
@ -95,11 +96,14 @@ class UserLoginStageView(ChallengeStageView):
self.logger.warning("User is not active, login will not work.")
delta = self.set_session_duration(remember)
self.set_session_ip()
login(
self.request,
user,
backend=backend,
)
# the `user_logged_in` signal will update the user to write the `last_login` field
# which we don't want to log as we already have a dedicated login event
with audit_ignore():
login(
self.request,
user,
backend=backend,
)
self.logger.debug(
"Logged in",
backend=backend,

View File

@ -16,7 +16,7 @@ entries:
placeholder: Username
placeholder_expression: false
required: true
type: text
type: username
field_key: username
label: Username
identifiers:

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.2.2 Blueprint schema",
"title": "authentik 2024.4.0 Blueprint schema",
"required": [
"version",
"entries"

View File

@ -11,7 +11,6 @@ entries:
name: "authentik default LDAP Mapping: DN to User Path"
object_field: "path"
expression: |
dn = ldap.get("distinguishedName")
path_elements = []
for pair in dn.split(","):
attr, _, value = pair.partition("=")

View File

@ -32,7 +32,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.2.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.4.0}
restart: unless-stopped
command: server
environment:
@ -53,7 +53,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.2.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.4.0}
restart: unless-stopped
command: worker
environment:

10
go.mod
View File

@ -1,15 +1,13 @@
module goauthentik.io
go 1.22
toolchain go1.22.0
go 1.22.2
require (
beryju.io/ldap v0.1.0
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/getsentry/sentry-go v0.27.0
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
github.com/go-ldap/ldap/v3 v3.4.7
github.com/go-ldap/ldap/v3 v3.4.8
github.com/go-openapi/runtime v0.28.0
github.com/go-openapi/strfmt v0.23.0
github.com/golang-jwt/jwt v3.2.2+incompatible
@ -30,7 +28,7 @@ require (
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.9.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2024022.11
goauthentik.io/api/v3 v3.2024023.2
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.19.0
golang.org/x/sync v0.7.0
@ -75,7 +73,7 @@ require (
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect

11
go.sum
View File

@ -84,8 +84,8 @@ github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 h1:O6yi4xa9b2D
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27/go.mod h1:AYvN8omj7nKLmbcXS2dyABYU6JB1Lz1bHmkkq1kf4I4=
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno=
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
github.com/go-ldap/ldap/v3 v3.4.7 h1:3Hbd7mIB1qjd3Ra59fI3JYea/t5kykFu2CVHBca9koE=
github.com/go-ldap/ldap/v3 v3.4.7/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -294,8 +294,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.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
goauthentik.io/api/v3 v3.2024022.11 h1:MlsaBwyMM9NtDvZcoaWvuNznPHXA0a5olnDLyr24REA=
goauthentik.io/api/v3 v3.2024022.11/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2024023.2 h1:lSVaZAKTpsDhtw11wnkGjPalkDzv9H2VKEJllBi2aXs=
goauthentik.io/api/v3 v3.2024023.2/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=
@ -373,8 +373,9 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

View File

@ -25,13 +25,14 @@ type Config struct {
}
type RedisConfig struct {
Host string `yaml:"host" env:"HOST, overwrite"`
Port int `yaml:"port" env:"PORT, overwrite"`
DB int `yaml:"db" env:"DB, overwrite"`
Username string `yaml:"username" env:"USERNAME, overwrite"`
Password string `yaml:"password" env:"PASSWORD, overwrite"`
TLS bool `yaml:"tls" env:"TLS, overwrite"`
TLSReqs string `yaml:"tls_reqs" env:"TLS_REQS, overwrite"`
Host string `yaml:"host" env:"HOST, overwrite"`
Port int `yaml:"port" env:"PORT, overwrite"`
DB int `yaml:"db" env:"DB, overwrite"`
Username string `yaml:"username" env:"USERNAME, overwrite"`
Password string `yaml:"password" env:"PASSWORD, overwrite"`
TLS bool `yaml:"tls" env:"TLS, overwrite"`
TLSReqs string `yaml:"tls_reqs" env:"TLS_REQS, overwrite"`
TLSCaCert *string `yaml:"tls_ca_certs" env:"TLS_CA_CERT, overwrite"`
}
type ListenConfig struct {

View File

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

View File

@ -2,6 +2,8 @@ package application
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"math"
"net/http"
@ -19,6 +21,7 @@ import (
"goauthentik.io/internal/outpost/proxyv2/codecs"
"goauthentik.io/internal/outpost/proxyv2/constants"
"goauthentik.io/internal/outpost/proxyv2/redisstore"
"goauthentik.io/internal/utils"
)
const RedisKeyPrefix = "authentik_proxy_session_"
@ -31,11 +34,40 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL)
maxAge = int(*t) + 1
}
if a.isEmbedded {
var tls *tls.Config
if config.Get().Redis.TLS {
tls = utils.GetTLSConfig()
switch strings.ToLower(config.Get().Redis.TLSReqs) {
case "none":
case "false":
tls.InsecureSkipVerify = true
case "required":
break
}
ca := config.Get().Redis.TLSCaCert
if ca != nil {
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
certs, err := os.ReadFile(*ca)
if err != nil {
a.log.WithError(err).Fatalf("Failed to append %s to RootCAs", *ca)
}
// Append our cert to the system pool
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
a.log.Println("No certs appended, using system certs only")
}
tls.RootCAs = rootCAs
}
}
client := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", config.Get().Redis.Host, config.Get().Redis.Port),
Username: config.Get().Redis.Username,
Password: config.Get().Redis.Password,
DB: config.Get().Redis.DB,
Addr: fmt.Sprintf("%s:%d", config.Get().Redis.Host, config.Get().Redis.Port),
Username: config.Get().Redis.Username,
Password: config.Get().Redis.Password,
DB: config.Get().Redis.DB,
TLSConfig: tls,
})
// New default RedisStore

View File

@ -54,7 +54,7 @@ function cleanup {
}
function prepare_debug {
poetry install --no-ansi --no-interaction
VIRTUAL_ENV=/ak-root/venv poetry install --no-ansi --no-interaction
touch /unittest.xml
chown authentik:authentik /unittest.xml
}

View File

@ -9,7 +9,7 @@ from psycopg import OperationalError, connect
from redis import Redis
from redis.exceptions import RedisError
from authentik.lib.config import CONFIG
from authentik.lib.config import CONFIG, redis_url
def check_postgres():
@ -35,24 +35,18 @@ def check_postgres():
def check_redis():
REDIS_PROTOCOL_PREFIX = "redis://"
if CONFIG.get_bool("redis.tls", False):
REDIS_PROTOCOL_PREFIX = "rediss://"
REDIS_URL = (
f"{REDIS_PROTOCOL_PREFIX}"
f"{quote_plus(CONFIG.get('redis.username'))}:"
f"{quote_plus(CONFIG.get('redis.password'))}@"
f"{quote_plus(CONFIG.get('redis.host'))}:"
f"{CONFIG.get_int('redis.port')}/{CONFIG.get('redis.db')}"
)
url = redis_url(CONFIG.get("redis.db"))
while True:
try:
redis = Redis.from_url(REDIS_URL)
redis = Redis.from_url(url)
redis.ping()
break
except RedisError as exc:
sleep(1)
CONFIG.log("info", f"Redis Connection failed, retrying... ({exc})", redis_url=REDIS_URL)
sanitized_url = url.replace(quote_plus(CONFIG.get("redis.password")), "******")
CONFIG.log(
"info", f"Redis Connection failed, retrying... ({exc})", redis_url=sanitized_url
)
CONFIG.log("info", "Redis Connection successful")

View File

@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-05 00:07+0000\n"
"POT-Creation-Date: 2024-04-16 00:07+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Marc Schmitt, 2024\n"
"Language-Team: French (https://app.transifex.com/authentik/teams/119923/fr/)\n"
@ -138,6 +138,14 @@ msgstr "Group"
msgid "Groups"
msgstr "Groupes"
#: authentik/core/models.py
msgid "Add user to group"
msgstr "Ajouter un utilisateur au groupe"
#: authentik/core/models.py
msgid "Remove user from group"
msgstr "Retirer l'utilisateur du groupe"
#: authentik/core/models.py
msgid "User's display name."
msgstr "Nom d'affichage de l'utilisateur"
@ -505,6 +513,22 @@ 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/stages/source/models.py
msgid ""
"Amount of time a user can take to return from the source to continue the "
"flow (Format: hours=-1;minutes=-2;seconds=-3)"
msgstr ""
"Durée que l'utilisateur peut prendre pour revenir de la source pour "
"continuer le flux (Format: hours=-1;minutes=-2;seconds=-3)"
#: authentik/enterprise/stages/source/models.py
msgid "Source Stage"
msgstr "Étape Source"
#: authentik/enterprise/stages/source/models.py
msgid "Source Stages"
msgstr "Étapes Source"
#: authentik/events/api/tasks.py
#, python-brace-format
msgid "Successfully started task {name}."
@ -1944,6 +1968,12 @@ msgstr "Les objets appliqués à ce filtre seront des groupes."
msgid "Field which contains a unique Identifier."
msgstr "Champ qui contient un identifiant unique."
#: authentik/sources/ldap/models.py
msgid "Update internal authentik password when login succeeds with LDAP"
msgstr ""
"Mettre à jour le mot de passe interne à authentik lorsque la connexion avec "
"LDAP réussi"
#: authentik/sources/ldap/models.py
msgid ""
"When a user changes their password, sync it back to LDAP. This can only be "
@ -2282,6 +2312,14 @@ msgstr "Connexion de l'utilisateur à la source SAML"
msgid "User SAML Source Connections"
msgstr "Connexion de l'utilisateur aux sources SAML"
#: authentik/sources/scim/models.py
msgid "SCIM Source"
msgstr "Source SCIM"
#: authentik/sources/scim/models.py
msgid "SCIM Sources"
msgstr "Sources SCIM"
#: authentik/stages/authenticator_duo/models.py
msgid "Duo Authenticator Setup Stage"
msgstr "Étape de configuration du Duo Authenticator"
@ -2395,8 +2433,20 @@ msgid "TOTP Devices"
msgstr "Équipements TOTP"
#: authentik/stages/authenticator_validate/challenge.py
msgid "Invalid Token"
msgstr "Jeton Invalide"
msgid ""
"Invalid Token. Please ensure the time on your device is accurate and try "
"again."
msgstr ""
"Jeton invalide. Merci de vous assurer que le temps défini sur votre appareil"
" est juste et de réessayer,"
#: authentik/stages/authenticator_validate/challenge.py
#: authentik/stages/authenticator_webauthn/stage.py
#, python-brace-format
msgid "Invalid device type. Contact your {brand} administrator for help."
msgstr ""
"Type d'appareil invalide. Merci de contacter l'administrateur de {brand} "
"pour de l'assistance."
#: authentik/stages/authenticator_validate/models.py
msgid "Static"
@ -2452,6 +2502,10 @@ msgstr "Étape de validation de l'authentificateur"
msgid "Authenticator Validation Stages"
msgstr "Étapes de validation de l'authentificateur"
#: authentik/stages/authenticator_validate/stage.py
msgid "No (allowed) MFA authenticator configured."
msgstr "Pas d'authentificateur MFA (autorisé) configuré."
#: authentik/stages/authenticator_webauthn/models.py
msgid "WebAuthn Authenticator Setup Stage"
msgstr "Étape de validation de l'authentificateur WebAuthn"
@ -2468,6 +2522,14 @@ msgstr "Appareil WebAuthn"
msgid "WebAuthn Devices"
msgstr "Équipements WebAuthn"
#: authentik/stages/authenticator_webauthn/models.py
msgid "WebAuthn Device type"
msgstr "Type d'appareil WebAuthn"
#: authentik/stages/authenticator_webauthn/models.py
msgid "WebAuthn Device types"
msgstr "Types d'appareil WebAuthn"
#: authentik/stages/captcha/models.py
msgid "Public key, acquired your captcha Provider."
msgstr "Clé publique, acquise auprès de votre fournisseur captcha."
@ -3129,6 +3191,14 @@ msgstr ""
msgid "Globally enable/disable impersonation."
msgstr "Activer/désactiver l'appropriation utilisateur de manière globale."
#: authentik/tenants/models.py
msgid "Default token duration"
msgstr "Durée par défaut des jetons"
#: authentik/tenants/models.py
msgid "Default token length"
msgstr "Longueur par défaut des jetons"
#: authentik/tenants/models.py
msgid "Tenant"
msgstr "Tenant"

Binary file not shown.

226
poetry.lock generated
View File

@ -2,87 +2,87 @@
[[package]]
name = "aiohttp"
version = "3.9.2"
version = "3.9.4"
description = "Async http client/server framework (asyncio)"
optional = false
python-versions = ">=3.8"
files = [
{file = "aiohttp-3.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:772fbe371788e61c58d6d3d904268e48a594ba866804d08c995ad71b144f94cb"},
{file = "aiohttp-3.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:edd4f1af2253f227ae311ab3d403d0c506c9b4410c7fc8d9573dec6d9740369f"},
{file = "aiohttp-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cfee9287778399fdef6f8a11c9e425e1cb13cc9920fd3a3df8f122500978292b"},
{file = "aiohttp-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc158466f6a980a6095ee55174d1de5730ad7dec251be655d9a6a9dd7ea1ff9"},
{file = "aiohttp-3.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54ec82f45d57c9a65a1ead3953b51c704f9587440e6682f689da97f3e8defa35"},
{file = "aiohttp-3.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abeb813a18eb387f0d835ef51f88568540ad0325807a77a6e501fed4610f864e"},
{file = "aiohttp-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc91d07280d7d169f3a0f9179d8babd0ee05c79d4d891447629ff0d7d8089ec2"},
{file = "aiohttp-3.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b65e861f4bebfb660f7f0f40fa3eb9f2ab9af10647d05dac824390e7af8f75b7"},
{file = "aiohttp-3.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:04fd8ffd2be73d42bcf55fd78cde7958eeee6d4d8f73c3846b7cba491ecdb570"},
{file = "aiohttp-3.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3d8d962b439a859b3ded9a1e111a4615357b01620a546bc601f25b0211f2da81"},
{file = "aiohttp-3.9.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:8ceb658afd12b27552597cf9a65d9807d58aef45adbb58616cdd5ad4c258c39e"},
{file = "aiohttp-3.9.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0e4ee4df741670560b1bc393672035418bf9063718fee05e1796bf867e995fad"},
{file = "aiohttp-3.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2dec87a556f300d3211decf018bfd263424f0690fcca00de94a837949fbcea02"},
{file = "aiohttp-3.9.2-cp310-cp310-win32.whl", hash = "sha256:3e1a800f988ce7c4917f34096f81585a73dbf65b5c39618b37926b1238cf9bc4"},
{file = "aiohttp-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:ea510718a41b95c236c992b89fdfc3d04cc7ca60281f93aaada497c2b4e05c46"},
{file = "aiohttp-3.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6aaa6f99256dd1b5756a50891a20f0d252bd7bdb0854c5d440edab4495c9f973"},
{file = "aiohttp-3.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a27d8c70ad87bcfce2e97488652075a9bdd5b70093f50b10ae051dfe5e6baf37"},
{file = "aiohttp-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:54287bcb74d21715ac8382e9de146d9442b5f133d9babb7e5d9e453faadd005e"},
{file = "aiohttp-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb3d05569aa83011fcb346b5266e00b04180105fcacc63743fc2e4a1862a891"},
{file = "aiohttp-3.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8534e7d69bb8e8d134fe2be9890d1b863518582f30c9874ed7ed12e48abe3c4"},
{file = "aiohttp-3.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd9d5b989d57b41e4ff56ab250c5ddf259f32db17159cce630fd543376bd96b"},
{file = "aiohttp-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa6904088e6642609981f919ba775838ebf7df7fe64998b1a954fb411ffb4663"},
{file = "aiohttp-3.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bda42eb410be91b349fb4ee3a23a30ee301c391e503996a638d05659d76ea4c2"},
{file = "aiohttp-3.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:193cc1ccd69d819562cc7f345c815a6fc51d223b2ef22f23c1a0f67a88de9a72"},
{file = "aiohttp-3.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b9f1cb839b621f84a5b006848e336cf1496688059d2408e617af33e3470ba204"},
{file = "aiohttp-3.9.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:d22a0931848b8c7a023c695fa2057c6aaac19085f257d48baa24455e67df97ec"},
{file = "aiohttp-3.9.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4112d8ba61fbd0abd5d43a9cb312214565b446d926e282a6d7da3f5a5aa71d36"},
{file = "aiohttp-3.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c4ad4241b52bb2eb7a4d2bde060d31c2b255b8c6597dd8deac2f039168d14fd7"},
{file = "aiohttp-3.9.2-cp311-cp311-win32.whl", hash = "sha256:ee2661a3f5b529f4fc8a8ffee9f736ae054adfb353a0d2f78218be90617194b3"},
{file = "aiohttp-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:4deae2c165a5db1ed97df2868ef31ca3cc999988812e82386d22937d9d6fed52"},
{file = "aiohttp-3.9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6f4cdba12539215aaecf3c310ce9d067b0081a0795dd8a8805fdb67a65c0572a"},
{file = "aiohttp-3.9.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:84e843b33d5460a5c501c05539809ff3aee07436296ff9fbc4d327e32aa3a326"},
{file = "aiohttp-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8008d0f451d66140a5aa1c17e3eedc9d56e14207568cd42072c9d6b92bf19b52"},
{file = "aiohttp-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61c47ab8ef629793c086378b1df93d18438612d3ed60dca76c3422f4fbafa792"},
{file = "aiohttp-3.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc71f748e12284312f140eaa6599a520389273174b42c345d13c7e07792f4f57"},
{file = "aiohttp-3.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a1c3a4d0ab2f75f22ec80bca62385db2e8810ee12efa8c9e92efea45c1849133"},
{file = "aiohttp-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a87aa0b13bbee025faa59fa58861303c2b064b9855d4c0e45ec70182bbeba1b"},
{file = "aiohttp-3.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2cc0d04688b9f4a7854c56c18aa7af9e5b0a87a28f934e2e596ba7e14783192"},
{file = "aiohttp-3.9.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1956e3ac376b1711c1533266dec4efd485f821d84c13ce1217d53e42c9e65f08"},
{file = "aiohttp-3.9.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:114da29f39eccd71b93a0fcacff178749a5c3559009b4a4498c2c173a6d74dff"},
{file = "aiohttp-3.9.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3f17999ae3927d8a9a823a1283b201344a0627272f92d4f3e3a4efe276972fe8"},
{file = "aiohttp-3.9.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:f31df6a32217a34ae2f813b152a6f348154f948c83213b690e59d9e84020925c"},
{file = "aiohttp-3.9.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7a75307ffe31329928a8d47eae0692192327c599113d41b278d4c12b54e1bd11"},
{file = "aiohttp-3.9.2-cp312-cp312-win32.whl", hash = "sha256:972b63d589ff8f305463593050a31b5ce91638918da38139b9d8deaba9e0fed7"},
{file = "aiohttp-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:200dc0246f0cb5405c80d18ac905c8350179c063ea1587580e3335bfc243ba6a"},
{file = "aiohttp-3.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:158564d0d1020e0d3fe919a81d97aadad35171e13e7b425b244ad4337fc6793a"},
{file = "aiohttp-3.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:da1346cd0ccb395f0ed16b113ebb626fa43b7b07fd7344fce33e7a4f04a8897a"},
{file = "aiohttp-3.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:eaa9256de26ea0334ffa25f1913ae15a51e35c529a1ed9af8e6286dd44312554"},
{file = "aiohttp-3.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1543e7fb00214fb4ccead42e6a7d86f3bb7c34751ec7c605cca7388e525fd0b4"},
{file = "aiohttp-3.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:186e94570433a004e05f31f632726ae0f2c9dee4762a9ce915769ce9c0a23d89"},
{file = "aiohttp-3.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d52d20832ac1560f4510d68e7ba8befbc801a2b77df12bd0cd2bcf3b049e52a4"},
{file = "aiohttp-3.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c45e4e815ac6af3b72ca2bde9b608d2571737bb1e2d42299fc1ffdf60f6f9a1"},
{file = "aiohttp-3.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa906b9bdfd4a7972dd0628dbbd6413d2062df5b431194486a78f0d2ae87bd55"},
{file = "aiohttp-3.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:68bbee9e17d66f17bb0010aa15a22c6eb28583edcc8b3212e2b8e3f77f3ebe2a"},
{file = "aiohttp-3.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4c189b64bd6d9a403a1a3f86a3ab3acbc3dc41a68f73a268a4f683f89a4dec1f"},
{file = "aiohttp-3.9.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8a7876f794523123bca6d44bfecd89c9fec9ec897a25f3dd202ee7fc5c6525b7"},
{file = "aiohttp-3.9.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:d23fba734e3dd7b1d679b9473129cd52e4ec0e65a4512b488981a56420e708db"},
{file = "aiohttp-3.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b141753be581fab842a25cb319f79536d19c2a51995d7d8b29ee290169868eab"},
{file = "aiohttp-3.9.2-cp38-cp38-win32.whl", hash = "sha256:103daf41ff3b53ba6fa09ad410793e2e76c9d0269151812e5aba4b9dd674a7e8"},
{file = "aiohttp-3.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:328918a6c2835861ff7afa8c6d2c70c35fdaf996205d5932351bdd952f33fa2f"},
{file = "aiohttp-3.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5264d7327c9464786f74e4ec9342afbbb6ee70dfbb2ec9e3dfce7a54c8043aa3"},
{file = "aiohttp-3.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07205ae0015e05c78b3288c1517afa000823a678a41594b3fdc870878d645305"},
{file = "aiohttp-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae0a1e638cffc3ec4d4784b8b4fd1cf28968febc4bd2718ffa25b99b96a741bd"},
{file = "aiohttp-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d43302a30ba1166325974858e6ef31727a23bdd12db40e725bec0f759abce505"},
{file = "aiohttp-3.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16a967685907003765855999af11a79b24e70b34dc710f77a38d21cd9fc4f5fe"},
{file = "aiohttp-3.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fa3ee92cd441d5c2d07ca88d7a9cef50f7ec975f0117cd0c62018022a184308"},
{file = "aiohttp-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b500c5ad9c07639d48615a770f49618130e61be36608fc9bc2d9bae31732b8f"},
{file = "aiohttp-3.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c07327b368745b1ce2393ae9e1aafed7073d9199e1dcba14e035cc646c7941bf"},
{file = "aiohttp-3.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cc7d6502c23a0ec109687bf31909b3fb7b196faf198f8cff68c81b49eb316ea9"},
{file = "aiohttp-3.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:07be2be7071723c3509ab5c08108d3a74f2181d4964e869f2504aaab68f8d3e8"},
{file = "aiohttp-3.9.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:122468f6fee5fcbe67cb07014a08c195b3d4c41ff71e7b5160a7bcc41d585a5f"},
{file = "aiohttp-3.9.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:00a9abcea793c81e7f8778ca195a1714a64f6d7436c4c0bb168ad2a212627000"},
{file = "aiohttp-3.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a9825fdd64ecac5c670234d80bb52bdcaa4139d1f839165f548208b3779c6c6"},
{file = "aiohttp-3.9.2-cp39-cp39-win32.whl", hash = "sha256:5422cd9a4a00f24c7244e1b15aa9b87935c85fb6a00c8ac9b2527b38627a9211"},
{file = "aiohttp-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:7d579dcd5d82a86a46f725458418458fa43686f6a7b252f2966d359033ffc8ab"},
{file = "aiohttp-3.9.2.tar.gz", hash = "sha256:b0ad0a5e86ce73f5368a164c10ada10504bf91869c05ab75d982c6048217fbf7"},
{file = "aiohttp-3.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:76d32588ef7e4a3f3adff1956a0ba96faabbdee58f2407c122dd45aa6e34f372"},
{file = "aiohttp-3.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:56181093c10dbc6ceb8a29dfeea1e815e1dfdc020169203d87fd8d37616f73f9"},
{file = "aiohttp-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7a5b676d3c65e88b3aca41816bf72831898fcd73f0cbb2680e9d88e819d1e4d"},
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1df528a85fb404899d4207a8d9934cfd6be626e30e5d3a5544a83dbae6d8a7e"},
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f595db1bceabd71c82e92df212dd9525a8a2c6947d39e3c994c4f27d2fe15b11"},
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c0b09d76e5a4caac3d27752027fbd43dc987b95f3748fad2b924a03fe8632ad"},
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689eb4356649ec9535b3686200b231876fb4cab4aca54e3bece71d37f50c1d13"},
{file = "aiohttp-3.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3666cf4182efdb44d73602379a66f5fdfd5da0db5e4520f0ac0dcca644a3497"},
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b65b0f8747b013570eea2f75726046fa54fa8e0c5db60f3b98dd5d161052004a"},
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1885d2470955f70dfdd33a02e1749613c5a9c5ab855f6db38e0b9389453dce7"},
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0593822dcdb9483d41f12041ff7c90d4d1033ec0e880bcfaf102919b715f47f1"},
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:47f6eb74e1ecb5e19a78f4a4228aa24df7fbab3b62d4a625d3f41194a08bd54f"},
{file = "aiohttp-3.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c8b04a3dbd54de6ccb7604242fe3ad67f2f3ca558f2d33fe19d4b08d90701a89"},
{file = "aiohttp-3.9.4-cp310-cp310-win32.whl", hash = "sha256:8a78dfb198a328bfb38e4308ca8167028920fb747ddcf086ce706fbdd23b2926"},
{file = "aiohttp-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:e78da6b55275987cbc89141a1d8e75f5070e577c482dd48bd9123a76a96f0bbb"},
{file = "aiohttp-3.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c111b3c69060d2bafc446917534150fd049e7aedd6cbf21ba526a5a97b4402a5"},
{file = "aiohttp-3.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:efbdd51872cf170093998c87ccdf3cb5993add3559341a8e5708bcb311934c94"},
{file = "aiohttp-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7bfdb41dc6e85d8535b00d73947548a748e9534e8e4fddd2638109ff3fb081df"},
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd9d334412961125e9f68d5b73c1d0ab9ea3f74a58a475e6b119f5293eee7ba"},
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35d78076736f4a668d57ade00c65d30a8ce28719d8a42471b2a06ccd1a2e3063"},
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:824dff4f9f4d0f59d0fa3577932ee9a20e09edec8a2f813e1d6b9f89ced8293f"},
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52b8b4e06fc15519019e128abedaeb56412b106ab88b3c452188ca47a25c4093"},
{file = "aiohttp-3.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eae569fb1e7559d4f3919965617bb39f9e753967fae55ce13454bec2d1c54f09"},
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:69b97aa5792428f321f72aeb2f118e56893371f27e0b7d05750bcad06fc42ca1"},
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d79aad0ad4b980663316f26d9a492e8fab2af77c69c0f33780a56843ad2f89e"},
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:d6577140cd7db19e430661e4b2653680194ea8c22c994bc65b7a19d8ec834403"},
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:9860d455847cd98eb67897f5957b7cd69fbcb436dd3f06099230f16a66e66f79"},
{file = "aiohttp-3.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:69ff36d3f8f5652994e08bd22f093e11cfd0444cea310f92e01b45a4e46b624e"},
{file = "aiohttp-3.9.4-cp311-cp311-win32.whl", hash = "sha256:e27d3b5ed2c2013bce66ad67ee57cbf614288bda8cdf426c8d8fe548316f1b5f"},
{file = "aiohttp-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d6a67e26daa686a6fbdb600a9af8619c80a332556245fa8e86c747d226ab1a1e"},
{file = "aiohttp-3.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c5ff8ff44825736a4065d8544b43b43ee4c6dd1530f3a08e6c0578a813b0aa35"},
{file = "aiohttp-3.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d12a244627eba4e9dc52cbf924edef905ddd6cafc6513849b4876076a6f38b0e"},
{file = "aiohttp-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dcad56c8d8348e7e468899d2fb3b309b9bc59d94e6db08710555f7436156097f"},
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7e69a7fd4b5ce419238388e55abd220336bd32212c673ceabc57ccf3d05b55"},
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4870cb049f10d7680c239b55428916d84158798eb8f353e74fa2c98980dcc0b"},
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2feaf1b7031ede1bc0880cec4b0776fd347259a723d625357bb4b82f62687b"},
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:939393e8c3f0a5bcd33ef7ace67680c318dc2ae406f15e381c0054dd658397de"},
{file = "aiohttp-3.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d2334e387b2adcc944680bebcf412743f2caf4eeebd550f67249c1c3696be04"},
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e0198ea897680e480845ec0ffc5a14e8b694e25b3f104f63676d55bf76a82f1a"},
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e40d2cd22914d67c84824045861a5bb0fb46586b15dfe4f046c7495bf08306b2"},
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:aba80e77c227f4234aa34a5ff2b6ff30c5d6a827a91d22ff6b999de9175d71bd"},
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:fb68dc73bc8ac322d2e392a59a9e396c4f35cb6fdbdd749e139d1d6c985f2527"},
{file = "aiohttp-3.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f3460a92638dce7e47062cf088d6e7663adb135e936cb117be88d5e6c48c9d53"},
{file = "aiohttp-3.9.4-cp312-cp312-win32.whl", hash = "sha256:32dc814ddbb254f6170bca198fe307920f6c1308a5492f049f7f63554b88ef36"},
{file = "aiohttp-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:63f41a909d182d2b78fe3abef557fcc14da50c7852f70ae3be60e83ff64edba5"},
{file = "aiohttp-3.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c3770365675f6be220032f6609a8fbad994d6dcf3ef7dbcf295c7ee70884c9af"},
{file = "aiohttp-3.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:305edae1dea368ce09bcb858cf5a63a064f3bff4767dec6fa60a0cc0e805a1d3"},
{file = "aiohttp-3.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f121900131d116e4a93b55ab0d12ad72573f967b100e49086e496a9b24523ea"},
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b71e614c1ae35c3d62a293b19eface83d5e4d194e3eb2fabb10059d33e6e8cbf"},
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:419f009fa4cfde4d16a7fc070d64f36d70a8d35a90d71aa27670bba2be4fd039"},
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b39476ee69cfe64061fd77a73bf692c40021f8547cda617a3466530ef63f947"},
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b33f34c9c7decdb2ab99c74be6443942b730b56d9c5ee48fb7df2c86492f293c"},
{file = "aiohttp-3.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c78700130ce2dcebb1a8103202ae795be2fa8c9351d0dd22338fe3dac74847d9"},
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:268ba22d917655d1259af2d5659072b7dc11b4e1dc2cb9662fdd867d75afc6a4"},
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:17e7c051f53a0d2ebf33013a9cbf020bb4e098c4bc5bce6f7b0c962108d97eab"},
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7be99f4abb008cb38e144f85f515598f4c2c8932bf11b65add0ff59c9c876d99"},
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:d58a54d6ff08d2547656356eea8572b224e6f9bbc0cf55fa9966bcaac4ddfb10"},
{file = "aiohttp-3.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7673a76772bda15d0d10d1aa881b7911d0580c980dbd16e59d7ba1422b2d83cd"},
{file = "aiohttp-3.9.4-cp38-cp38-win32.whl", hash = "sha256:e4370dda04dc8951012f30e1ce7956a0a226ac0714a7b6c389fb2f43f22a250e"},
{file = "aiohttp-3.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:eb30c4510a691bb87081192a394fb661860e75ca3896c01c6d186febe7c88530"},
{file = "aiohttp-3.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:84e90494db7df3be5e056f91412f9fa9e611fbe8ce4aaef70647297f5943b276"},
{file = "aiohttp-3.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d4845f8501ab28ebfdbeab980a50a273b415cf69e96e4e674d43d86a464df9d"},
{file = "aiohttp-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69046cd9a2a17245c4ce3c1f1a4ff8c70c7701ef222fce3d1d8435f09042bba1"},
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b73a06bafc8dcc508420db43b4dd5850e41e69de99009d0351c4f3007960019"},
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:418bb0038dfafeac923823c2e63226179976c76f981a2aaad0ad5d51f2229bca"},
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71a8f241456b6c2668374d5d28398f8e8cdae4cce568aaea54e0f39359cd928d"},
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:935c369bf8acc2dc26f6eeb5222768aa7c62917c3554f7215f2ead7386b33748"},
{file = "aiohttp-3.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4e48c8752d14ecfb36d2ebb3d76d614320570e14de0a3aa7a726ff150a03c"},
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:916b0417aeddf2c8c61291238ce25286f391a6acb6f28005dd9ce282bd6311b6"},
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9b6787b6d0b3518b2ee4cbeadd24a507756ee703adbac1ab6dc7c4434b8c572a"},
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:221204dbda5ef350e8db6287937621cf75e85778b296c9c52260b522231940ed"},
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:10afd99b8251022ddf81eaed1d90f5a988e349ee7d779eb429fb07b670751e8c"},
{file = "aiohttp-3.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2506d9f7a9b91033201be9ffe7d89c6a54150b0578803cce5cb84a943d075bc3"},
{file = "aiohttp-3.9.4-cp39-cp39-win32.whl", hash = "sha256:e571fdd9efd65e86c6af2f332e0e95dad259bfe6beb5d15b3c3eca3a6eb5d87b"},
{file = "aiohttp-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:7d29dd5319d20aa3b7749719ac9685fbd926f71ac8c77b2477272725f882072d"},
{file = "aiohttp-3.9.4.tar.gz", hash = "sha256:6ff71ede6d9a5a58cfb7b6fffc83ab5d4a63138276c771ac91ceaaddf5459644"},
]
[package.dependencies]
@ -547,13 +547,13 @@ test = ["coverage (>=7)", "hypothesis", "pytest"]
[[package]]
name = "celery"
version = "5.3.6"
version = "5.4.0"
description = "Distributed Task Queue."
optional = false
python-versions = ">=3.8"
files = [
{file = "celery-5.3.6-py3-none-any.whl", hash = "sha256:9da4ea0118d232ce97dff5ed4974587fb1c0ff5c10042eb15278487cdd27d1af"},
{file = "celery-5.3.6.tar.gz", hash = "sha256:870cc71d737c0200c397290d730344cc991d13a057534353d124c9380267aab9"},
{file = "celery-5.4.0-py3-none-any.whl", hash = "sha256:369631eb580cf8c51a82721ec538684994f8277637edde2dfc0dacd73ed97f64"},
{file = "celery-5.4.0.tar.gz", hash = "sha256:504a19140e8d3029d5acad88330c541d4c3f64c789d85f94756762d8bca7e706"},
]
[package.dependencies]
@ -569,7 +569,7 @@ vine = ">=5.1.0,<6.0"
[package.extras]
arangodb = ["pyArango (>=2.0.2)"]
auth = ["cryptography (==41.0.5)"]
auth = ["cryptography (==42.0.5)"]
azureblockblob = ["azure-storage-blob (>=12.15.0)"]
brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
cassandra = ["cassandra-driver (>=3.25.0,<4)"]
@ -579,22 +579,23 @@ couchbase = ["couchbase (>=3.0.0)"]
couchdb = ["pycouchdb (==1.14.2)"]
django = ["Django (>=2.2.28)"]
dynamodb = ["boto3 (>=1.26.143)"]
elasticsearch = ["elastic-transport (<=8.10.0)", "elasticsearch (<=8.11.0)"]
elasticsearch = ["elastic-transport (<=8.13.0)", "elasticsearch (<=8.13.0)"]
eventlet = ["eventlet (>=0.32.0)"]
gcs = ["google-cloud-storage (>=2.10.0)"]
gevent = ["gevent (>=1.5.0)"]
librabbitmq = ["librabbitmq (>=2.0.0)"]
memcache = ["pylibmc (==1.6.3)"]
mongodb = ["pymongo[srv] (>=4.0.2)"]
msgpack = ["msgpack (==1.0.7)"]
pymemcache = ["python-memcached (==1.59)"]
msgpack = ["msgpack (==1.0.8)"]
pymemcache = ["python-memcached (>=1.61)"]
pyro = ["pyro4 (==4.82)"]
pytest = ["pytest-celery (==0.0.0)"]
pytest = ["pytest-celery[all] (>=1.0.0)"]
redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"]
s3 = ["boto3 (>=1.26.143)"]
slmq = ["softlayer-messaging (>=1.0.3)"]
solar = ["ephem (==4.1.5)"]
sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"]
sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"]
sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.4)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"]
tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
yaml = ["PyYAML (>=3.10)"]
zookeeper = ["kazoo (>=1.3.1)"]
@ -1612,22 +1613,23 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"]
[[package]]
name = "gunicorn"
version = "21.2.0"
version = "22.0.0"
description = "WSGI HTTP Server for UNIX"
optional = false
python-versions = ">=3.5"
python-versions = ">=3.7"
files = [
{file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"},
{file = "gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"},
{file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"},
{file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"},
]
[package.dependencies]
packaging = "*"
[package.extras]
eventlet = ["eventlet (>=0.24.1)"]
eventlet = ["eventlet (>=0.24.1,!=0.36.0)"]
gevent = ["gevent (>=1.4.0)"]
setproctitle = ["setproctitle"]
testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"]
tornado = ["tornado (>=0.2)"]
[[package]]
@ -3525,28 +3527,28 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.3.7"
version = "0.4.0"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"},
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"},
{file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"},
{file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"},
{file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"},
{file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"},
{file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"},
{file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"},
{file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"},
{file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"},
{file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"},
{file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:70b8c620cf2212744eabd6d69c4f839f2be0d8880d27beaeb0adb6aa0b316aa8"},
{file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa3e3ff53be05a8c5570c1585ea1e089f6b399ca99fcb78598d4a8234f248db"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5616cca501d1d16b932b7e607d7e1fd1b8c8c51d6ee484b7940fc1adc5bea541"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46eff08dd480b5d9b540846159fe134d70e3c45a3c913c600047cbf7f0e4e308"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d546f511431fff2b17adcf7110f3b2c2c0c8d33b0e10e5fd27fd340bc617efc"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c7b6b6b38e216036284c5779b6aa14acbf5664e3b5872533219cf93daf40ddfb"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e1cf8b064bb2a6b4922af7274fe2dffcb552d96ba716b2fbe5e2c970ed7de18"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9911c9046b94253e1fa844c0192bb764b86866a881502dee324686474d498c17"},
{file = "ruff-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ca7a971c8f1a0b6f5ff4a819c0d1c2619536530bbd5a289af725d8b2ef1013d"},
{file = "ruff-0.4.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:752e0f77f421141dd470a0b1bed4fd8f763aebabe32c80ed3580f740ef4ba807"},
{file = "ruff-0.4.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:84f2a5dd8f33964d826c5377e094f7ce11e55e432cd42d3bf64efe4384224a03"},
{file = "ruff-0.4.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0b20e7db4a672495320a8a18149b7febf4e4f97509a4657367144569ce0915fd"},
{file = "ruff-0.4.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0b0eddd339e24dc4f7719b1cde4967f6b6bc0ad948cc183711ba8910f14aeafe"},
{file = "ruff-0.4.0-py3-none-win32.whl", hash = "sha256:e70befd488271a2c28c80bd427f73d8855dd222fc549fa1e9967d287c5cfe781"},
{file = "ruff-0.4.0-py3-none-win_amd64.whl", hash = "sha256:8584b9361900997ccf8d7aaa4dc4ab43e258a853ca7189d98ac929dc9ee50875"},
{file = "ruff-0.4.0-py3-none-win_arm64.whl", hash = "sha256:fea4ec813c965e40af29ee627a1579ee1d827d77e81d54b85bdd7b42d1540cdd"},
{file = "ruff-0.4.0.tar.gz", hash = "sha256:7457308d9ebf00d6a1c9a26aa755e477787a636c90b823f91cd7d4bea9e89260"},
]
[[package]]
@ -3963,13 +3965,13 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "9.0.4"
version = "9.0.5"
description = "Twilio API client and TwiML generator"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-9.0.4-py2.py3-none-any.whl", hash = "sha256:086abae1a575a0ee89a72c0792d814ee349fe55c8df76b563ecfc49463c3c533"},
{file = "twilio-9.0.4.tar.gz", hash = "sha256:d493d5bde6361bb713dffec00b9465ff84978b71334dd75002152e79604688ba"},
{file = "twilio-9.0.5-py2.py3-none-any.whl", hash = "sha256:5e09e910b9368f50f23cb3c3dd5ba77164d80a81e9d97db955cbac322deb2a4e"},
{file = "twilio-9.0.5.tar.gz", hash = "sha256:e9b5727943584d25d618fe502f0100fc5283215f31c863f80b5c64581b4702b0"},
]
[package.dependencies]

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "authentik"
version = "2024.2.2"
version = "2024.4.0"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2024.2.2
version: 2024.4.0
description: Making authentication simple.
contact:
email: hello@goauthentik.io
@ -44714,6 +44714,26 @@ components:
- num_pk
- parent_name
- pk
UserGroupRequest:
type: object
description: Simplified Group Serializer for user's groups
properties:
name:
type: string
minLength: 1
maxLength: 80
is_superuser:
type: boolean
description: Users added to this group will be superusers.
parent:
type: string
format: uuid
nullable: true
attributes:
type: object
additionalProperties: {}
required:
- name
UserLoginChallenge:
type: object
description: Empty challenge
@ -45400,7 +45420,11 @@ components:
- $ref: '#/components/schemas/WebAuthnDeviceType'
readOnly: true
nullable: true
aaguid:
type: string
readOnly: true
required:
- aaguid
- created_on
- device_type
- name

View File

@ -6,7 +6,6 @@ from typing import Any
from docker.types import Healthcheck
from authentik.core.models import Token, TokenIntents, User
from authentik.lib.generators import generate_id
from authentik.lib.utils.http import get_http_session
from authentik.sources.scim.models import SCIMSource
@ -40,18 +39,9 @@ class TestSourceSCIM(SeleniumTestCase):
@retry()
def test_scim_conformance(self):
user = User.objects.create(
username=generate_id(),
)
token = Token.objects.create(
user=user,
intent=TokenIntents.INTENT_API,
expiring=False,
)
source = SCIMSource.objects.create(
name=generate_id(),
slug=generate_id(),
token=token,
)
session = get_http_session()
test_launch = session.post(
@ -59,7 +49,7 @@ class TestSourceSCIM(SeleniumTestCase):
data={
"endPoint": self.live_server_url + f"/source/scim/{source.slug}/v2",
"username": "foo",
"password": token.key,
"password": source.token.key,
"jwtToken": None,
"usersCheck": 1,
"groupsCheck": 1,

View File

@ -6,7 +6,7 @@
"": {
"name": "@goauthentik/web-tests",
"dependencies": {
"chromedriver": "^123.0.3"
"chromedriver": "^123.0.4"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
@ -2084,9 +2084,9 @@
}
},
"node_modules/chromedriver": {
"version": "123.0.3",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-123.0.3.tgz",
"integrity": "sha512-35IeTqDLcVR0htF9nD/Lh+g24EG088WHVKXBXiFyWq+2lelnoM0B3tKTBiUEjLng0GnELI4QyQPFK7i97Fz1fQ==",
"version": "123.0.4",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-123.0.4.tgz",
"integrity": "sha512-3Yi7y7q35kkSAOTbRisiww/SL2w+DqafDPAaUShpSuLMmPaOvHQR0i3bm2/33QBiQ8fUb1J/MzppzVL6IDqvhA==",
"hasInstallScript": true,
"dependencies": {
"@testim/chrome-version": "^1.1.4",

View File

@ -32,6 +32,6 @@
"node": ">=20"
},
"dependencies": {
"chromedriver": "^123.0.3"
"chromedriver": "^123.0.4"
}
}

5051
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,22 +38,22 @@
"@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.5",
"@fortawesome/fontawesome-free": "^6.5.2",
"@goauthentik/api": "^2024.2.2-1713289394",
"@goauthentik/api": "^2024.2.3-1713441634",
"@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.1",
"@lit/localize": "^0.12.1",
"@lit/reactive-element": "^2.0.4",
"@open-wc/lit-helpers": "^0.7.0",
"@patternfly/elements": "^3.0.0",
"@patternfly/elements": "^3.0.1",
"@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^7.110.1",
"@sentry/browser": "^7.111.0",
"@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1",
"chart.js": "^4.4.2",
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.36.1",
"core-js": "^3.37.0",
"country-flag-icons": "^1.5.11",
"fuse.js": "^7.0.0",
"guacamole-common-js": "^1.5.0",
@ -81,13 +81,13 @@
"@lit/localize-tools": "^0.7.2",
"@rollup/plugin-replace": "^5.0.5",
"@spotlightjs/spotlight": "^1.2.17",
"@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-links": "^7.6.17",
"@storybook/addon-essentials": "^8.0.8",
"@storybook/addon-links": "^8.0.8",
"@storybook/api": "^7.6.17",
"@storybook/blocks": "^7.6.4",
"@storybook/manager-api": "^7.6.17",
"@storybook/web-components": "^7.6.17",
"@storybook/web-components-vite": "^7.6.17",
"@storybook/blocks": "^8.0.8",
"@storybook/manager-api": "^8.0.8",
"@storybook/web-components": "^8.0.8",
"@storybook/web-components-vite": "^8.0.8",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/chart.js": "^2.9.41",
"@types/codemirror": "5.60.15",
@ -117,8 +117,8 @@
"react-dom": "^18.2.0",
"rollup-plugin-modify": "^3.0.0",
"rollup-plugin-postcss-lit": "^2.1.0",
"storybook": "^7.6.17",
"storybook-addon-mock": "^4.3.0",
"storybook": "^8.0.8",
"storybook-addon-mock": "^5.0.0",
"ts-lit-plugin": "^2.0.2",
"tslib": "^2.6.2",
"turnstile-types": "^1.2.1",

View File

@ -166,7 +166,7 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(AKElement) {
${this.renderNewVersionMessage()}
${this.renderImpersonationMessage()}
${map(sidebarContent, renderOneSidebarItem)}
${this.renderEnterpriseMessage()}
${this.renderEnterpriseMenu()}
`;
}
@ -199,7 +199,7 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(AKElement) {
: nothing;
}
renderEnterpriseMessage() {
renderEnterpriseMenu() {
return this.can(CapabilitiesEnum.IsEnterprise)
? html`
<ak-sidebar-item>

View File

@ -3,6 +3,8 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/ak-dual-select/ak-dual-select-provider";
import { DataProvision, DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
import "@goauthentik/elements/chips/Chip";
import "@goauthentik/elements/chips/ChipGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -12,22 +14,17 @@ import YAML from "yaml";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
CoreApi,
CoreGroupsListRequest,
Group,
PaginatedRoleList,
RbacApi,
} from "@goauthentik/api";
import { CoreApi, CoreGroupsListRequest, Group, RbacApi, Role } from "@goauthentik/api";
export function rbacRolePair(item: Role): DualSelectPair {
return [item.pk, html`<div class="selection-main">${item.name}</div>`, item.name];
}
@customElement("ak-group-form")
export class GroupForm extends ModelForm<Group, string> {
@state()
roles?: PaginatedRoleList;
static get styles(): CSSResult[] {
return super.styles.concat(css`
.pf-c-button.pf-m-control {
@ -51,12 +48,6 @@ export class GroupForm extends ModelForm<Group, string> {
: msg("Successfully created group.");
}
async load(): Promise<void> {
this.roles = await new RbacApi(DEFAULT_CONFIG).rbacRolesList({
ordering: "name",
});
}
async send(data: Group): Promise<Group> {
if (this.instance?.pk) {
return new CoreApi(DEFAULT_CONFIG).coreGroupsPartialUpdate({
@ -127,24 +118,29 @@ export class GroupForm extends ModelForm<Group, string> {
</ak-search-select>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Roles")} name="roles">
<select class="pf-c-form-control" multiple>
${this.roles?.results.map((role) => {
const selected = Array.from(this.instance?.roles || []).some((sp) => {
return sp == role.pk;
});
return html`<option value=${role.pk} ?selected=${selected}>
${role.name}
</option>`;
})}
</select>
<ak-dual-select-provider
.provider=${(page: number, search?: string): Promise<DataProvision> => {
return new RbacApi(DEFAULT_CONFIG)
.rbacRolesList({
page: page,
search: search,
})
.then((results) => {
return {
pagination: results.pagination,
options: results.results.map(rbacRolePair),
};
});
}}
.selected=${(this.instance?.rolesObj ?? []).map(rbacRolePair)}
available-label="${msg("Available Roles")}"
selected-label="${msg("Selected Roles")}"
></ak-dual-select-provider>
<p class="pf-c-form__helper-text">
${msg(
"Select roles to grant this groups' users' permissions from the selected roles.",
)}
</p>
<p class="pf-c-form__helper-text">
${msg("Hold control/command to select multiple items.")}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Attributes")}

View File

@ -110,10 +110,7 @@ export class UserWriteStageForm extends BaseStageForm<UserWriteStage> {
${msg("Mark newly created users as inactive.")}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("User path template")}
name="userPathTemplate"
>
<ak-form-element-horizontal label=${msg("User type")} name="userType">
<ak-radio
.options=${[
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2024.2.2";
export const VERSION = "2024.4.0";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -1,5 +1,6 @@
import { EVENT_REFRESH } from "@goauthentik/authentik/common/constants";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { globalAK } from "@goauthentik/common/global";
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
import { ContextProvider } from "@lit/context";
@ -23,6 +24,9 @@ export class ConfigContextController implements ReactiveController {
context: authentikConfigContext,
initialValue: undefined,
});
// Pre-hydrate from template-embedded config
this.context.setValue(globalAK().config);
this.host.config = globalAK().config;
this.fetch = this.fetch.bind(this);
this.fetch();
}

View File

@ -1,18 +1,15 @@
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
import { EVENT_LOCALE_REQUEST } from "@goauthentik/common/constants";
import { customEvent, isCustomEvent } from "@goauthentik/elements/utils/customEvents";
import { EVENT_LOCALE_CHANGE, EVENT_LOCALE_REQUEST } from "@goauthentik/common/constants";
import { customEvent } from "@goauthentik/elements/utils/customEvents";
import { LitElement, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { customElement, property, state } from "lit/decorators.js";
import { WithBrandConfig } from "../Interface/brandProvider";
import { initializeLocalization } from "./configureLocale";
import type { LocaleGetter, LocaleSetter } from "./configureLocale";
import {
DEFAULT_LOCALE,
autoDetectLanguage,
getBestMatchLocale,
localeCodeFromUrl,
} from "./helpers";
import { DEFAULT_LOCALE, autoDetectLanguage, getBestMatchLocale } from "./helpers";
const LocaleContextBase = WithBrandConfig(LitElement);
/**
* A component to manage your locale settings.
@ -28,7 +25,7 @@ import {
* @fires ak-locale-change - When a valid locale has been swapped in
*/
@customElement("ak-locale-context")
export class LocaleContext extends LitElement {
export class LocaleContext extends LocaleContextBase {
/// @attribute The text representation of the current locale */
@property({ attribute: true, type: String })
locale = DEFAULT_LOCALE;
@ -41,6 +38,9 @@ export class LocaleContext extends LitElement {
setLocale: LocaleSetter;
@state()
userLocale = "";
constructor(code = DEFAULT_LOCALE) {
super();
this.notifyApplication = this.notifyApplication.bind(this);
@ -59,8 +59,15 @@ export class LocaleContext extends LitElement {
connectedCallback() {
super.connectedCallback();
const localeRequest = autoDetectLanguage(this.locale);
this.updateLocale(localeRequest);
// Commenting out until we can come up with a better way of separating the
// "request user identity" with the session expiration heartbeat.
/*
new CoreApi(DEFAULT_CONFIG)
.coreUsersMeRetrieve()
.then((user) => (this.userLocale = user?.user?.settings?.locale ?? ""))
.catch(() => {});
*/
this.updateLocale();
window.addEventListener(EVENT_LOCALE_REQUEST, this.updateLocaleHandler);
}
@ -69,28 +76,19 @@ export class LocaleContext extends LitElement {
super.disconnectedCallback();
}
updateLocaleHandler(ev: Event) {
if (!isCustomEvent(ev)) {
console.warn(`Received a non-custom event at EVENT_LOCALE_REQUEST: ${ev}`);
return;
}
updateLocaleHandler(_ev: Event) {
console.debug("authentik/locale: Locale update request received.");
this.updateLocale(ev.detail.locale);
this.updateLocale();
}
updateLocale(code: string) {
const urlCode = localeCodeFromUrl(this.param);
const requestedLocale = urlCode ? urlCode : code;
const locale = getBestMatchLocale(requestedLocale);
updateLocale() {
const localeRequest = autoDetectLanguage(this.userLocale, this.brand?.defaultLocale);
const locale = getBestMatchLocale(localeRequest);
if (!locale) {
console.warn(`authentik/locale: failed to find locale for code ${code}`);
console.warn(`authentik/locale: failed to find locale for code ${localeRequest}`);
return;
}
locale.locale().then(() => {
console.debug(`authentik/locale: Loaded locale '${code}'`);
if (this.getLocale() === code) {
return;
}
console.debug(`Setting Locale to ... ${locale.label()} (${locale.code})`);
this.setLocale(locale.code).then(() => {
window.setTimeout(this.notifyApplication, 0);

View File

@ -45,12 +45,13 @@ export function localeCodeFromUrl(param = "locale") {
const isLocaleCandidate = (v: unknown): v is string =>
typeof v === "string" && v !== "" && v !== TOMBSTONE;
export function autoDetectLanguage(requestedCode?: string): string {
export function autoDetectLanguage(userReq = TOMBSTONE, brandReq = TOMBSTONE): string {
const localeCandidates: string[] = [
globalAK()?.locale ?? TOMBSTONE,
localeCodeFromUrl("locale"),
requestedCode ?? TOMBSTONE,
userReq,
window.navigator?.language ?? TOMBSTONE,
brandReq,
globalAK()?.locale ?? TOMBSTONE,
DEFAULT_LOCALE,
].filter(isLocaleCandidate);

View File

@ -28,11 +28,11 @@ export class LogViewer extends Table<LogEvent> {
pagination: {
next: 0,
previous: 0,
count: 1,
count: this.logs?.length || 0,
current: 1,
totalPages: 1,
startIndex: 1,
endIndex: 1,
endIndex: this.logs?.length || 0,
},
results: this.logs || [],
};

View File

@ -208,7 +208,7 @@ export class SidebarItem extends AKElement {
}
renderWithLabel() {
html`
return html`
<span class="pf-c-nav__link">
<slot name="label"></slot>
</span>

View File

@ -516,7 +516,7 @@ export class FlowExecutor extends Interface implements StageHost {
? html`
<li>
<a
href="https://unsplash.com/@theforestbirds"
href="https://unsplash.com/@sorasagano"
>${msg("Background image")}</a
>
</li>

View File

@ -6531,6 +6531,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -6800,6 +6800,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -6448,6 +6448,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -8447,117 +8447,158 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="s00bcaadd620a11f8">
<source>Latest version unknown</source>
<target>Dernière version inconnue</target>
</trans-unit>
<trans-unit id="s10fedec3a779ea63">
<source>Timestamp</source>
<target>Horodatage</target>
</trans-unit>
<trans-unit id="s48e186fb300e5464">
<source>Time</source>
<target>Temps</target>
</trans-unit>
<trans-unit id="saa8aa81ad6f055fd">
<source>Level</source>
<target>Niveau</target>
</trans-unit>
<trans-unit id="sd0ea7366ebc403ff">
<source>Event</source>
<target>Évènement</target>
</trans-unit>
<trans-unit id="s225f3e57c6a0d635">
<source>Logger</source>
<target>Logger</target>
</trans-unit>
<trans-unit id="s39d6971531a270b6">
<source>Update internal password on login</source>
<target>Mettre à jour le mot de passe interne à la connexion</target>
</trans-unit>
<trans-unit id="sefe04e319223a3d6">
<source>When the user logs in to authentik using this source password backend, update their credentials in authentik.</source>
<target>Lorsqu'un utilisateur se connecte à authentik en utilisant le backend de mot de passe de cette source, mettre à jour ses identifiants dans authentik.</target>
</trans-unit>
<trans-unit id="s5f43af3669b1e098">
<source>Source</source>
<target>Source</target>
</trans-unit>
<trans-unit id="sd9f752de8448bcc9">
<source>Resume timeout</source>
<target>Délai de reprise</target>
</trans-unit>
<trans-unit id="s517954806d7610f2">
<source>Amount of time a user can take to return from the source to continue the flow.</source>
<target>Durée que l'utilisateur peut prendre pour revenir de la source pour continuer le flux.</target>
</trans-unit>
<trans-unit id="s8c4bc6e515949112">
<source>Your Install ID</source>
<target>Votre ID d'installation</target>
</trans-unit>
<trans-unit id="s8cc0075913c67566">
<source>Enter the email associated with your account, and we'll send you a link to reset your password.</source>
<target>Entrer l'email associé à votre compte, et nous vous enverrons un lien pour réinitialiser votre mot de passe.</target>
</trans-unit>
<trans-unit id="s06bfe45ffef2cf60">
<source>Stage name: <x id="0" equiv-text="${this.challenge.name}"/></source>
<target>Nom de l'étape : <x id="0" equiv-text="${this.challenge.name}"/></target>
</trans-unit>
<trans-unit id="s90064dd5c4dde2c6">
<source>Please scan the QR code above using the Microsoft Authenticator, Google Authenticator, or other authenticator apps on your device, and enter the code the device displays below to finish setting up the MFA device.</source>
<target>Merci de scanner le QR code ci-dessus avec Microsoft Authenticator, Google Authenticator ou une autre application d'authentification à deux facteurs sur votre appareil, et entrer le code que l'appareil affiche ci-dessous pour finir la configuration de votre appareil MFA.</target>
</trans-unit>
<trans-unit id="s02160dc6adba3456">
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
<target>Injecte une source OAuth ou SAML dans lexécution du flux. Cela permet d'effectuer des vérifications additionnelles sur l'utilisateur, ou d'accéder dynamiquement à plusieurs sources pour des identifiants utilisateurs différents (nom d'utilisateur, adresse courriel, etc).</target>
</trans-unit>
<trans-unit id="sc7d071fb5cc1f6bf">
<source>A selection is required</source>
<target>Une sélection est requise</target>
</trans-unit>
<trans-unit id="sa64fb483becc9c2c">
<source>Device type restrictions</source>
<target>Restrictions de type d'appareil</target>
</trans-unit>
<trans-unit id="sbb928551c84cd63f">
<source>Available Device types</source>
<target>Types d'appareil disponibles</target>
</trans-unit>
<trans-unit id="s6446c35d6b411e53">
<source>Selected Device types</source>
<target>Types d'appareil sélectionnés</target>
</trans-unit>
<trans-unit id="s1f4df216b56de4ac">
<source>Optionally restrict which WebAuthn device types may be used. When no device types are selected, all devices are allowed.</source>
<target>Optionnel, restreindre quels types d'appareil WebAuthn peuvent être utilisés. Lorsqu'aucun type d'appareil n'est sélectionné, tout les appareils sont autorisés.</target>
</trans-unit>
<trans-unit id="s23ed998c51cbe38f">
<source>If the user has successfully authenticated with a device in the classes listed above within this configured duration, this stage will be skipped.</source>
<target>Si un utilisateur s'est authentifié avec succès avec un type d'appareil contenu dans ceux listés ci-dessus dans le temps configuré ici, cette étape sera passée.</target>
</trans-unit>
<trans-unit id="s4d4f52ccfd9d6adf">
<source>WebAuthn-specific settings</source>
<target>Réglages spécifiques à WebAuthn</target>
</trans-unit>
<trans-unit id="sb46d2e64f64c6284">
<source>WebAuthn Device type restrictions</source>
<target>Restrictions de type d'appareil WebAuthn</target>
</trans-unit>
<trans-unit id="s11274960b13cf21a">
<source>This restriction only applies to devices created in authentik 2024.4 or later.</source>
<target>Les restrictions ne s'appliquent qu'aux appareils créés dans authentik 2024.4 ou ultérieur.</target>
</trans-unit>
<trans-unit id="s4888252cbd785175">
<source>Default token duration</source>
<target>Durée par défaut des jetons</target>
</trans-unit>
<trans-unit id="s25c80a16a07871ba">
<source>Default duration for generated tokens</source>
<target>Durée par défaut des jetons générés</target>
</trans-unit>
<trans-unit id="se5c9ffc025fdf61d">
<source>Default token length</source>
<target>Longueur par défaut des jetons</target>
</trans-unit>
<trans-unit id="sa6b2c110466d1754">
<source>Default length of generated tokens</source>
<target>Longueur par défaut des jetons générés</target>
</trans-unit>
<trans-unit id="s1f25e1e20469a9ea">
<source>deleted</source>
<target>supprimé</target>
</trans-unit>
<trans-unit id="s0ca04e397298bc43">
<source>Select permissions to assign</source>
<target>Sélectionner les permissions à assigner</target>
</trans-unit>
<trans-unit id="s676d94e7e31a8075">
<source>SCIM Source is in preview.</source>
<target>La source SCIM est en aperçu.</target>
</trans-unit>
<trans-unit id="s31f1afc0a81977c1">
<source>Update SCIM Source</source>
<target>Mettre à jour la source SCIM</target>
</trans-unit>
<trans-unit id="s4bb356adc8a7f85b">
<source>SCIM Base URL</source>
<target>URL de base SCIM</target>
</trans-unit>
<trans-unit id="sb23304fc42c5d6d9">
<source>Provisioned Users</source>
<target>Utilisateurs provisionnés</target>
</trans-unit>
<trans-unit id="s6a81ee82b2e5ecbb">
<source>Provisioned Groups</source>
<target>Groupes provisionnés</target>
</trans-unit>
<trans-unit id="s10154dbd4fbc697b">
<source>removed</source>
<target>supprimé</target>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
<target>Vérification...</target>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -8386,6 +8386,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -8230,6 +8230,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -6652,6 +6652,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -8502,4 +8502,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body></file></xliff>

View File

@ -6441,6 +6441,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -5359,6 +5359,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -596,9 +596,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>未找到 URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot;。</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>未找到 URL "
<x id="0" equiv-text="${this.url}"/>"。</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1040,8 +1040,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 &quot;.*&quot;。请注意这可能带来的安全影响。</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1782,8 +1782,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 &quot;fa-test&quot;。</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2961,8 +2961,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 &quot;memberUid&quot; 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3739,8 +3739,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 &quot;minutes=5&quot;。</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -3916,10 +3916,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>您确定要更新
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; 吗?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -4995,7 +4995,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>像 YubiKey 这样的“漫游”身份验证器</target>
</trans-unit>
@ -5330,10 +5330,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;,类型为
<x id="0" equiv-text="${prompt.name}"/>"
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
<x id="2" equiv-text="${prompt.type}"/></target>
</trans-unit>
@ -5382,7 +5382,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>如果设置时长大于 0用户可以选择“保持登录”选项这将使用户的会话延长此处设置的时间。</target>
</trans-unit>
@ -7830,7 +7830,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>成功创建用户并添加到组 <x id="0" equiv-text="${this.group.name}"/></target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>此用户将会被添加到组 &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;。</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -8598,7 +8598,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
<target>正在验证...</target>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -6489,6 +6489,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -8347,6 +8347,9 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s30d6ff9e15e0a40a">
<source>Verifying...</source>
</trans-unit>
<trans-unit id="sc1673c93148583ba">
<source>Request failed. Please try again later.</source>
</trans-unit>
</body>
</file>

View File

@ -0,0 +1,15 @@
---
title: API Clients
---
These API clients are officially supported and maintained.
:::info
These API clients are primarily built around creating/updating/deleting configuration objects in authentik, and in most cases can **not** be used to implemented SSO into your application.
:::
| Language | Package name | URL |
| --------------------- | ----------------------- | ---------------------------------------------- |
| JavaScript/Typescript | `@goauthentik/api` | https://www.npmjs.com/package/@goauthentik/api |
| Go | `goauthentik.io/api/v3` | https://pkg.go.dev/goauthentik.io/api/v3 |
| Python | `authentik_client` | https://pypi.org/project/authentik-client/ |

View File

@ -58,3 +58,11 @@ When enabled, all the events caused by a user will be deleted upon the user's de
### Impersonation
Globally enable/disable impersonation. Defaults to `true`.
### Default token duration
Default duration for generated tokens. Defaults to `minutes=30`.
### Default token length
Default length of generated tokens. Defaults to 60.

View File

@ -21,7 +21,9 @@ Using the `Not configured action`, you can choose what happens when a user does
By default, authenticator validation is required every time the flow containing this stage is executed. To only change this behavior, set _Last validation threshold_ to a non-zero value. (Requires authentik 2022.5)
Keep in mind that when using Code-based devices (TOTP, Static and SMS), values lower than `seconds=30` cannot be used, as with the way TOTP devices are saved, there is no exact timestamp.
### Less-frequent validation
### Options
#### Less-frequent validation
:::info
Requires authentik 2022.5.1
@ -29,12 +31,13 @@ Requires authentik 2022.5.1
You can configure this stage to only ask for MFA validation if the user hasn't authenticated themselves within a defined time period. To configure this, set _Last validation threshold_ to any non-zero value. Any of the users devices within the selected classes are checked.
### Passwordless authentication
#### Passwordless authentication
:::info
Requires authentik 2021.12.4
:::
:::danger
:::caution
Firefox has some known issues regarding FIDO (see https://bugzilla.mozilla.org/show_bug.cgi?id=1530370) and TouchID (see https://bugzilla.mozilla.org/show_bug.cgi?id=1536482)
:::
@ -48,7 +51,7 @@ As final stage, bind a _User login_ stage.
Users can either access this flow directly via its URL, or you can modify any Identification stage's _Passwordless flow_ setting to add a direct link to this flow.
### Logging
#### Logging
Logins which used Passwordless authentication have the _auth_method_ context variable set to `auth_webauthn_pwl`, and the device used is saved in the arguments. Example:
@ -73,7 +76,7 @@ Logins which used Passwordless authentication have the _auth_method_ context var
}
```
### `WebAuthn Device type restrictions`
#### WebAuthn Device type restrictions
:::info
Requires authentik 2024.4

View File

@ -4,19 +4,21 @@ title: WebAuthn authenticator setup stage
This stage configures a WebAuthn-based Authenticator. This can either be a browser, biometrics or a Security stick like a YubiKey.
### `User verification`
### Options
#### User verification
Configure if authentik should require, prefer or discourage user verification for the authenticator. For example when using a virtual authenticator like Windows Hello, this setting controls if a PIN is required.
### `Resident key requirement`
#### Resident key requirement
Configure if the created authenticator is stored in the encrypted memory on the device or in persistent memory. When configuring [passwordless login](../identification/index.md#passwordless-flow), this should be set to either _Preferred_ or _Required_, otherwise the authenticator cannot be used for passwordless authentication.
### `Authenticator Attachment`
#### Authenticator Attachment
Configure if authentik will require either a removable device (like a YubiKey, Google Titan, etc) or a non-removable device (like Windows Hello, TouchID or password managers), or not send a requirement.
### `Device type restrictions`
#### Device type restrictions
:::info
Requires authentik 2024.4

View File

@ -98,8 +98,8 @@ Templates are rendered using Django's templating engine. The following variables
{% block content %}
<tr>
<td class="alert alert-success">
{% blocktrans with username=user.username %} Hi {{ username }}, {%
endblocktrans %}
{% blocktrans with username=user.username %} Hi {{ username }},
{% endblocktrans %}
</td>
</tr>
<tr>

View File

@ -38,12 +38,20 @@ It is very important that the configured source's authentication and enrollment
This is because the Source stage works by appending a [dynamic in-memory](../../../core/terminology.md#dynamic-in-memory-stage) stage to the source's flow, so having a [User login stage](../user_login/index.md) bound will cause the source's flow to not resume the original flow it was started from, and instead directly authenticating the pending user.
### Example use case
This stage can be used to leverage an external OAuth/SAML identity provider.
For example, you can authenticate users by routing them through a custom device-health solution.
Another use case is to route users to authenticate with your legacy (Okta, etc) IdP and then use the returned identity and attributes within authentik as part of an authorization flow, for example as part of an IdP migration. For authentication/enrollment this is also possible with an [OAuth](../../../../integrations/sources/oauth/)/[SAML](../../../../integrations/sources/saml/) source by itself.
### Options
#### `source`
#### Source
The source the user is redirected to. Must be a web-based source, such as [OAuth](../../../../integrations/sources/oauth/) or [SAML](../../../../integrations/sources/saml/). Sources like [LDAP](../../../../integrations/sources/ldap/) are _not_ compatible.
#### `resume_timeout`
#### Resume timeout
Because the execution of the current flow is suspended before the user is redirected to the configured source, this option configures how long the suspended flow is saved. If this timeout is exceeded, upon return from the configured source, the suspended flow will restart from the beginning.

View File

@ -72,7 +72,7 @@ To check if your config has been applied correctly, you can run the following co
- `AUTHENTIK_POSTGRESQL__PASSWORD`: Database password, defaults to the environment variable `POSTGRES_PASSWORD`
- `AUTHENTIK_POSTGRESQL__USE_PGBOUNCER`: Adjust configuration to support connection to PgBouncer
- `AUTHENTIK_POSTGRESQL__USE_PGPOOL`: Adjust configuration to support connection to Pgpool
- `AUTHENTIK_POSTGRESQL__SSLMODE`: Strictness of ssl verification. Defaults to `verify-ca`
- `AUTHENTIK_POSTGRESQL__SSLMODE`: Strictness of ssl verification. Defaults to `"verify-ca"`
- `AUTHENTIK_POSTGRESQL__SSLROOTCERT`: CA root for server ssl verification
- `AUTHENTIK_POSTGRESQL__SSLCERT`: Path to x509 client certificate to authenticate to server
- `AUTHENTIK_POSTGRESQL__SSLKEY`: Path to private key of `SSLCERT` certificate
@ -85,7 +85,8 @@ To check if your config has been applied correctly, you can run the following co
- `AUTHENTIK_REDIS__USERNAME`: Redis server username when not using configuration URL
- `AUTHENTIK_REDIS__PASSWORD`: Redis server password when not using configuration URL
- `AUTHENTIK_REDIS__TLS`: Redis server connection using TLS when not using configuration URL
- `AUTHENTIK_REDIS__TLS_REQS`: Redis server TLS connection requirements when not using configuration URL
- `AUTHENTIK_REDIS__TLS_REQS`: Redis server TLS connection requirements when not using configuration URL. Defaults to `"none"`. Allowed values are `"none"` and `"required"`.
- `AUTHENTIK_REDIS__TLS_CA_CERT`: Path to the Redis server TLS CA root when not using configuration URL. Defaults to `null`.
## Result Backend Settings
@ -312,6 +313,14 @@ Configure how long reputation scores should be saved for in seconds. Note that t
Defaults to `86400`.
### `AUTHENTIK_SESSION_STORAGE`
:::info
Requires authentik 2024.4
:::
Configure if the sessions are stored in the cache or the database. Defaults to `cache`. Allowed values are `cache` and `db`. Note that changing this value will invalidate all previous sessions.
### `AUTHENTIK_WEB__WORKERS`
:::info

View File

@ -51,7 +51,7 @@ Run the following commands to generate a password and secret key and write them
{/* prettier-ignore */}
```shell
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60)" >> .env
```
:::info

View File

@ -23,9 +23,9 @@ password=my-token
This will return a JSON response with an `access_token`, which is a signed JWT token. This token can be sent along requests to other hosts, which can then validate the JWT based on the signing key configured in authentik.
Starting with authentik 2024.next, it is also possible to encode the username and token of the user to authenticate with, separated with a colon, into a base64 string and pass it as `client_secret` value.
Starting with authentik 2024.4, it is also possible to encode the username and token of the user to authenticate with, separated with a colon, into a base64 string and pass it as `client_secret` value.
In addition to that, with authentik 2024.next it is also possible to pass the configured `client_secret` value, which will automatically generate a service account user for which the JWT token will be issued.
In addition to that, with authentik 2024.4 it is also possible to pass the configured `client_secret` value, which will automatically generate a service account user for which the JWT token will be issued.
### JWT-authentication

View File

@ -1,60 +0,0 @@
---
title: Release next
slug: /releases/next
---
<!-- ## Breaking changes -->
## Breaking changes
### Manual action is required
### Manual action may be required
- **Configuration options migrated to the Admin interface**
The following config options have been moved from the config file and can now be set using the Admin interface (under **System** -> **Settings**) or the API:
- `AUTHENTIK_DEFAULT_TOKEN_LENGTH`
When upgrading to 2024.next, the currently configured options will be automatically migrated to the database, and can be removed from the `.env` or helm values file afterwards.
## New features
- Configurable app password token expiring
Thanks @jmdilly for contributing this feature!
Admins can now configure the default token duration (which defaults to `minutes=30`) in the admin interface as specified above. This value can also be overridden per-user with the `goauthentik.io/user/token-maximum-lifetime` attribute.
## Upgrading
This release does not introduce any new requirements.
### docker-compose
To upgrade, download the new docker-compose file and update the Docker stack with the new version, using these commands:
```shell
wget -O docker-compose.yml https://goauthentik.io/version/xxxx.x/docker-compose.yml
docker compose up -d
```
The `-O` flag retains the downloaded file's name, overwriting any existing local file with the same name.
### Kubernetes
Upgrade the Helm Chart to the new version, using the following commands:
```shell
helm repo update
helm upgrade authentik authentik/authentik -f values.yaml --version ^xxxx.x
```
## Minor changes/fixes
<!-- _Insert the output of `make gen-changelog` here_ -->
## API Changes
<!-- _Insert output of `make gen-diff` here_ -->

View File

@ -321,10 +321,6 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2024.2
## Fixed in 2024.2.2
- ci: do not push docker image if fork (#8724)
- ci: fix missing DOCKER_USERNAME secret (#8730)
- ci: fix missing DOCKER_USERNAME secret (cherry-pick #8730) (#8733)
- ci: fix missing output on composite action (cherry-pick #8741) (#8742)
- core: fix blueprint export (cherry-pick #8695) (#8696)
- enterprise: fix read_only activating when no license is installed (cherry-pick #8697) (#8698)
- enterprise: force license usage update after change to license (cherry-pick #8723) (#8725)
@ -338,6 +334,19 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2024.2
- web/admin: don't mark property mappings as required anywhere (cherry-pick #8752) (#8755)
- web/admin: don't mark remaining property mappings as required (cherry-pick #8772) (#8773)
## Fixed in 2024.2.3
- api: capabilities: properly set can_save_media when s3 is enabled (cherry-pick #8896) (#8897)
- enterprise: only check for valid license existing for creating Enterprise objects (cherry-pick #8813) (#8822)
- enterprise/rac: fix connection token management (cherry-pick #8909) (#8912)
- events: discard notification if user has empty email (cherry-pick #8938) (#8951)
- events: fix incorrect user logged when using API token authentication (#9302)
- lifecycle: migrate: ensure template schema exists before migrating (cherry-pick #8952) (#9022)
- stages/email: Disable autoescape for text templates (cherry-pick #8812) (#8824)
- stages/email: fix issue when sending emails to users with same display as email (cherry-pick #8850) (#8852)
- stages/user_write: ensure user data is json-serializable (cherry-pick #8926) (#8928)
- tenants: really ensure default tenant cannot be deleted (cherry-pick #8875) (#8876)
## API Changes
#### What's New

View File

@ -0,0 +1,104 @@
---
title: Release 2024.4
slug: /releases/2024.4
---
:::::note
2024.4 has not been released yet! We're publishing these release notes as a preview of what's to come, and for our awesome beta testers trying out release candidates.
To try out the release candidate, replace your Docker image tag with the latest release candidate number, such as 2024.4.0-rc1. You can find the latest one in [the latest releases on GitHub](https://github.com/goauthentik/authentik/releases). If you don't find any, it means we haven't released one yet.
:::::
## Highlights
- **OAuth/SAML as authentication factor** <span class="badge badge--primary">Enterprise</span> Use an external provider as part of an MFA authentication flow, including custom implementations
- **SCIM Source** <span class="badge badge--info">Preview</span> Provision users and groups in authentik using an SCIM API
- **Configurable WebAuthn device restrictions** Configure which types of WebAuthn devices can be used to enroll and validate for different authorization levels.
- **Performance improvements** The API Endpoints to list Users, Groups, and Events have been optimized by 100%, y% and z% respectively
## Breaking changes
### Manual action may be required
- **Configuration options migrated to the Admin interface**
The following config options have been moved from the config file and can now be set using the Admin interface (under **System** -> **Settings**) or the API:
- `AUTHENTIK_DEFAULT_TOKEN_LENGTH`
When upgrading to 2024.4, the currently configured options will be automatically migrated to the database, and can be removed from the `.env` or helm values file afterwards.
## New features
- **Source stage** <span class="badge badge--primary">Enterprise</span>
The source stage allows for an inclusion of a source as part of a flow. This can be used to link a user to a source as part of their authentication/enrollment, or it can be used as an external multi-factor to provide device health attestation for example.
For details refer to [Source stage](../../flow/stages/source/index.md)
- **SCIM Source** <span class="badge badge--info">Preview</span>
Provision users and groups in authentik using an SCIM API.
For details refer to [SCIM Source](../../../integrations/sources/scim/)
- **Configurable WebAuthn device restrictions**
Configure which types of WebAuthn devices can be used to enroll and validate for different authorization levels.
For details refer to [WebAuthn authenticator setup stage](../../flow/stages/authenticator_webauthn/index.md)
- **Revamped UI for log messages**
Log messages from several API endpoints are now shown with much greater detail, which helps with implementing custom policies and property mappings.
- **Python API Client**
There's now an official API Client for Python: https://pypi.org/project/authentik-client/. This API Client can be used to create/update/delete objects within authentik as well as using the Flow executor to authenticate.
- **Configure LDAP sources to not store hashed password in authentik**
When authentik is configured to federate with an LDAP source, upon authentication, authentik hashed the password and stored it in its own database. This allows authentication to function when LDAP is unreachable. Admins can now configure this behavior for when this is not desirable.
For details refer to [LDAP Source](../../../integrations/sources/ldap/)
- **Configurable app password token expiring**
Thanks @jmdilly for contributing this feature!
Admins can now configure the default token duration (which defaults to `minutes=30`) in the admin interface as specified above. This value can also be overridden per-user with the `goauthentik.io/user/token-maximum-lifetime` attribute.
## Upgrading
This release does not introduce any new requirements.
### docker-compose
To upgrade, download the new docker-compose file and update the Docker stack with the new version, using these commands:
```shell
wget -O docker-compose.yml https://goauthentik.io/version/2024.4/docker-compose.yml
docker compose up -d
```
The `-O` flag retains the downloaded file's name, overwriting any existing local file with the same name.
### Kubernetes
Upgrade the Helm Chart to the new version, using the following commands:
```shell
helm repo update
helm upgrade authentik authentik/authentik -f values.yaml --version ^2024.4
```
## Minor changes/fixes
<!-- _Insert the output of `make gen-changelog` here_ -->
## API Changes
<!-- _Insert output of `make gen-diff` here_ -->

View File

@ -3,6 +3,12 @@ title: Release xxxx.x
slug: "/releases/xxxx.x"
---
:::::note
xxxx.x has not been released yet! We're publishing these release notes as a preview of what's to come, and for our awesome beta testers trying out release candidates.
To try out the release candidate, replace your Docker image tag with the latest release candidate number, such as xxxx.x.0-rc1. You can find the latest one in [the latest releases on GitHub](https://github.com/goauthentik/authentik/releases). If you don't find any, it means we haven't released one yet.
:::::
<!-- ## Breaking changes -->
## New features

View File

@ -1,11 +1,9 @@
---
title: LDAP
title: LDAP Source
---
Sources allow you to connect authentik to an existing user directory. They can also be used for social logins, using external providers such as Facebook, Twitter, etc.
## LDAP Source
This source allows you to import users and groups from an LDAP Server.
:::info
@ -54,7 +52,7 @@ Be aware of the following security considerations when turning on this functiona
- Updating the LDAP password does not invalid the password stored in authentik, however for LDAP Servers like FreeIPA and Active Directory, authentik will lock its internal password during the next LDAP sync. For other LDAP servers, the old passwords will still be valid indefinitely.
- Logging in via LDAP credentials overwrites the password stored in authentik if users have different passwords in LDAP and authentik.
- Custom security measures used to secure the password in LDAP may differ from the ones used in authentik. Depending on thread model and security requirements this could lead to unknowingly being non-compliant.
- Custom security measures used to secure the password in LDAP may differ from the ones used in authentik. Depending on threat model and security requirements this could lead to unknowingly being non-compliant.
## Troubleshooting

View File

@ -1,5 +1,5 @@
---
title: OAuth
title: OAuth Source
---
:::note

View File

@ -1,5 +1,5 @@
---
title: SCIM source
title: SCIM Source
---
:::info
@ -10,14 +10,20 @@ The SCIM source allows other applications to directly create users and groups wi
The base SCIM URL is in the format of `https://authentik.company/source/scim/<source-slug>/v2`. Authentication is done via Bearer tokens that are generated by authentik. When an SCIM source is created, a service account is created and a matching token is provided.
## First steps
To set up an SCIM source, log in as an administrator into authentik. Navigate to **Directory->Federation & Social login**, and click on **Create**. Select the **SCIM Source** type in the wizard, and give the source a name.
After the source is created, click on the name of the source in the list, and you will see the **SCIM Base URL** which is used by the SCIM client. Use the **Click to copy token** button to copy the token which is used by the client to authenticate SCIM requests.
## Supported Options & Resource types
### `/v2/Users`
Endpoint to list, create, patch, and delete users.
Endpoint to list, create, update and delete users.
### `/v2/Groups`
Endpoint to list, create, patch, and delete groups.
Endpoint to list, create, update and delete groups.
There is also the `/v2/ServiceProviderConfig` and `/v2/ResourceTypes`, which is used by SCIM-enabled applications to find out which features authentik supports.

View File

@ -343,13 +343,14 @@ const docsSidebar = {
description: "Release notes for recent authentik versions",
},
items: [
"releases/2024/v2024.4",
"releases/2024/v2024.2",
"releases/2023/v2023.10",
"releases/2023/v2023.8",
{
type: "category",
label: "Previous versions",
items: [
"releases/2023/v2023.8",
"releases/2023/v2023.6",
"releases/2023/v2023.5",
"releases/2023/v2023.4",

View File

@ -47,6 +47,7 @@ module.exports = {
"api/making-schema-changes",
"api/websocket",
"api/browser",
"api/clients",
],
},
{