Compare commits
101 Commits
version/20
...
web/legibi
Author | SHA1 | Date | |
---|---|---|---|
1bc8fa0a9d | |||
91572b8621 | |||
080d31f189 | |||
15b59594e2 | |||
b4e295a14a | |||
b590b6be44 | |||
15ee3d3566 | |||
aea6c7adbe | |||
42a2337200 | |||
ffdd49e176 | |||
b41231141c | |||
88d3b7f5a4 | |||
2b39748c84 | |||
93b93517be | |||
6da55dc8aa | |||
b93dc48030 | |||
7aba4b0c01 | |||
d5572a2570 | |||
55b1ddff6e | |||
77c913bfd3 | |||
69b80e5bb5 | |||
ba63399a7b | |||
86893d83b8 | |||
85ab201803 | |||
2c96b24b62 | |||
1f2cbca833 | |||
c2db998041 | |||
18a70e93a1 | |||
3123b3ac5e | |||
f2e1b6d466 | |||
6bcacd744b | |||
e5af964d9d | |||
122b95197b | |||
8d4e7f5d55 | |||
9d32ba261a | |||
b5a9b645f4 | |||
46303cc59f | |||
4af415f3fd | |||
ef82143811 | |||
c7567e031a | |||
3b2cd9e8d6 | |||
261e18b3d6 | |||
51a0f7d314 | |||
041ffef812 | |||
68b4d58ebd | |||
881571bd14 | |||
64a0f66e62 | |||
7d5cda4c25 | |||
8ba2679036 | |||
d98523f243 | |||
6da0548fa2 | |||
8734710e61 | |||
64b996aa1f | |||
dbe91cbc55 | |||
a56e037eae | |||
b8f1e2fac0 | |||
e1b56aac05 | |||
794731eed7 | |||
19fbc2a022 | |||
38e467bf8e | |||
9e32cf361b | |||
42a5a43640 | |||
8d5b835c4f | |||
ca3b948895 | |||
a714c781a6 | |||
df2e3878d5 | |||
1370c32aea | |||
0ae373bc1e | |||
6facb5872e | |||
c67de17dd8 | |||
2128e7f45f | |||
0e7a4849f6 | |||
85343fa5d4 | |||
3ec0d30965 | |||
50d2f69332 | |||
7d972ec711 | |||
854427e463 | |||
be349e2e14 | |||
bd0e81b8ad | |||
f6afb59515 | |||
dddde09be5 | |||
6d7fc94698 | |||
1dcf9108ad | |||
7bb6a3dfe6 | |||
9cc440eee1 | |||
fe9e4526ac | |||
20b66f850c | |||
67b327414b | |||
5b8d86b5a9 | |||
67aed3e318 | |||
9809b94030 | |||
e7527c551b | |||
36b10b434a | |||
831797b871 | |||
5cc2c0f45f | |||
32442766f4 | |||
75790909a8 | |||
e0d5df89ca | |||
f25a9c624e | |||
914993a788 | |||
89dad07a66 |
@ -1,16 +1,16 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 2024.12.3
|
current_version = 2025.2.0
|
||||||
tag = True
|
tag = True
|
||||||
commit = 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*))?
|
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?
|
||||||
serialize =
|
serialize =
|
||||||
{major}.{minor}.{patch}-{rc_t}{rc_n}
|
{major}.{minor}.{patch}-{rc_t}{rc_n}
|
||||||
{major}.{minor}.{patch}
|
{major}.{minor}.{patch}
|
||||||
message = release: {new_version}
|
message = release: {new_version}
|
||||||
tag_name = version/{new_version}
|
tag_name = version/{new_version}
|
||||||
|
|
||||||
[bumpversion:part:rc_t]
|
[bumpversion:part:rc_t]
|
||||||
values =
|
values =
|
||||||
rc
|
rc
|
||||||
final
|
final
|
||||||
optional_value = final
|
optional_value = final
|
||||||
|
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -28,7 +28,11 @@ Output of docker-compose logs or kubectl logs respectively
|
|||||||
|
|
||||||
**Version and Deployment (please complete the following information):**
|
**Version and Deployment (please complete the following information):**
|
||||||
|
|
||||||
- authentik version: [e.g. 2021.8.5]
|
<!--
|
||||||
|
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- authentik version: [e.g. 2025.2.0]
|
||||||
- Deployment: [e.g. docker-compose, helm]
|
- Deployment: [e.g. docker-compose, helm]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
7
.github/ISSUE_TEMPLATE/question.md
vendored
7
.github/ISSUE_TEMPLATE/question.md
vendored
@ -20,7 +20,12 @@ Output of docker-compose logs or kubectl logs respectively
|
|||||||
|
|
||||||
**Version and Deployment (please complete the following information):**
|
**Version and Deployment (please complete the following information):**
|
||||||
|
|
||||||
- authentik version: [e.g. 2021.8.5]
|
<!--
|
||||||
|
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
- authentik version: [e.g. 2025.2.0]
|
||||||
- Deployment: [e.g. docker-compose, helm]
|
- Deployment: [e.g. docker-compose, helm]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
2
.github/actions/setup/action.yml
vendored
2
.github/actions/setup/action.yml
vendored
@ -35,7 +35,7 @@ runs:
|
|||||||
run: |
|
run: |
|
||||||
export PSQL_TAG=${{ inputs.postgresql_version }}
|
export PSQL_TAG=${{ inputs.postgresql_version }}
|
||||||
docker compose -f .github/actions/setup/docker-compose.yml up -d
|
docker compose -f .github/actions/setup/docker-compose.yml up -d
|
||||||
poetry install --sync
|
poetry sync
|
||||||
cd web && npm ci
|
cd web && npm ci
|
||||||
- name: Generate config
|
- name: Generate config
|
||||||
shell: poetry run python {0}
|
shell: poetry run python {0}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
---
|
---
|
||||||
name: authentik-backend-translate-extract-compile
|
name: authentik-translate-extract-compile
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *" # every day at midnight
|
- cron: "0 0 * * *" # every day at midnight
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- version-*
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POSTGRES_DB: authentik
|
POSTGRES_DB: authentik
|
||||||
@ -32,6 +36,7 @@ jobs:
|
|||||||
poetry run ak compilemessages
|
poetry run ak compilemessages
|
||||||
make web-check-compile
|
make web-check-compile
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate_token.outputs.token }}
|
token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
@ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
|
|||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| --------- | --------- |
|
| --------- | --------- |
|
||||||
| 2024.10.x | ✅ |
|
|
||||||
| 2024.12.x | ✅ |
|
| 2024.12.x | ✅ |
|
||||||
|
| 2025.2.x | ✅ |
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
__version__ = "2024.12.3"
|
__version__ = "2025.2.0"
|
||||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ from authentik.enterprise.providers.microsoft_entra.models import (
|
|||||||
MicrosoftEntraProviderGroup,
|
MicrosoftEntraProviderGroup,
|
||||||
MicrosoftEntraProviderUser,
|
MicrosoftEntraProviderUser,
|
||||||
)
|
)
|
||||||
from authentik.enterprise.providers.rac.models import ConnectionToken
|
|
||||||
from authentik.enterprise.providers.ssf.models import StreamEvent
|
from authentik.enterprise.providers.ssf.models import StreamEvent
|
||||||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
|
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
|
||||||
EndpointDevice,
|
EndpointDevice,
|
||||||
@ -72,6 +71,7 @@ from authentik.providers.oauth2.models import (
|
|||||||
DeviceToken,
|
DeviceToken,
|
||||||
RefreshToken,
|
RefreshToken,
|
||||||
)
|
)
|
||||||
|
from authentik.providers.rac.models import ConnectionToken
|
||||||
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
|
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
|
||||||
from authentik.rbac.models import Role
|
from authentik.rbac.models import Role
|
||||||
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
|
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
|
||||||
|
@ -35,8 +35,7 @@ from authentik.flows.planner import (
|
|||||||
FlowPlanner,
|
FlowPlanner,
|
||||||
)
|
)
|
||||||
from authentik.flows.stage import StageView
|
from authentik.flows.stage import StageView
|
||||||
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
|
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET
|
||||||
from authentik.lib.utils.urls import redirect_with_qs
|
|
||||||
from authentik.lib.views import bad_request_message
|
from authentik.lib.views import bad_request_message
|
||||||
from authentik.policies.denied import AccessDeniedResponse
|
from authentik.policies.denied import AccessDeniedResponse
|
||||||
from authentik.policies.utils import delete_none_values
|
from authentik.policies.utils import delete_none_values
|
||||||
@ -47,8 +46,9 @@ from authentik.stages.user_write.stage import PLAN_CONTEXT_USER_PATH
|
|||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
SESSION_KEY_OVERRIDE_FLOW_TOKEN = "authentik/flows/source_override_flow_token" # nosec
|
|
||||||
PLAN_CONTEXT_SOURCE_GROUPS = "source_groups"
|
PLAN_CONTEXT_SOURCE_GROUPS = "source_groups"
|
||||||
|
SESSION_KEY_SOURCE_FLOW_STAGES = "authentik/flows/source_flow_stages"
|
||||||
|
SESSION_KEY_OVERRIDE_FLOW_TOKEN = "authentik/flows/source_override_flow_token" # nosec
|
||||||
|
|
||||||
|
|
||||||
class MessageStage(StageView):
|
class MessageStage(StageView):
|
||||||
@ -219,28 +219,28 @@ class SourceFlowManager:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
flow_context.update(self.policy_context)
|
flow_context.update(self.policy_context)
|
||||||
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
|
||||||
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
|
||||||
self._logger.info("Replacing source flow with overridden flow", flow=token.flow.slug)
|
|
||||||
plan = token.plan
|
|
||||||
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
|
||||||
plan.context.update(flow_context)
|
|
||||||
for stage in self.get_stages_to_append(flow):
|
|
||||||
plan.append_stage(stage)
|
|
||||||
if stages:
|
|
||||||
for stage in stages:
|
|
||||||
plan.append_stage(stage)
|
|
||||||
self.request.session[SESSION_KEY_PLAN] = plan
|
|
||||||
flow_slug = token.flow.slug
|
|
||||||
token.delete()
|
|
||||||
return redirect_with_qs(
|
|
||||||
"authentik_core:if-flow",
|
|
||||||
self.request.GET,
|
|
||||||
flow_slug=flow_slug,
|
|
||||||
)
|
|
||||||
flow_context.setdefault(PLAN_CONTEXT_REDIRECT, final_redirect)
|
flow_context.setdefault(PLAN_CONTEXT_REDIRECT, final_redirect)
|
||||||
|
|
||||||
if not flow:
|
if not flow:
|
||||||
|
# We only check for the flow token here if we don't have a flow, otherwise we rely on
|
||||||
|
# SESSION_KEY_SOURCE_FLOW_STAGES to delegate the usage of this token and dynamically add
|
||||||
|
# stages that deal with this token to return to another flow
|
||||||
|
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
||||||
|
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
||||||
|
self._logger.info(
|
||||||
|
"Replacing source flow with overridden flow", flow=token.flow.slug
|
||||||
|
)
|
||||||
|
plan = token.plan
|
||||||
|
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||||
|
plan.context.update(flow_context)
|
||||||
|
for stage in self.get_stages_to_append(flow):
|
||||||
|
plan.append_stage(stage)
|
||||||
|
if stages:
|
||||||
|
for stage in stages:
|
||||||
|
plan.append_stage(stage)
|
||||||
|
redirect = plan.to_redirect(self.request, token.flow)
|
||||||
|
token.delete()
|
||||||
|
return redirect
|
||||||
return bad_request_message(
|
return bad_request_message(
|
||||||
self.request,
|
self.request,
|
||||||
_("Configured flow does not exist."),
|
_("Configured flow does not exist."),
|
||||||
@ -259,6 +259,8 @@ class SourceFlowManager:
|
|||||||
if stages:
|
if stages:
|
||||||
for stage in stages:
|
for stage in stages:
|
||||||
plan.append_stage(stage)
|
plan.append_stage(stage)
|
||||||
|
for stage in self.request.session.get(SESSION_KEY_SOURCE_FLOW_STAGES, []):
|
||||||
|
plan.append_stage(stage)
|
||||||
return plan.to_redirect(self.request, flow)
|
return plan.to_redirect(self.request, flow)
|
||||||
|
|
||||||
def handle_auth(
|
def handle_auth(
|
||||||
@ -295,6 +297,8 @@ class SourceFlowManager:
|
|||||||
# When request isn't authenticated we jump straight to auth
|
# When request isn't authenticated we jump straight to auth
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
return self.handle_auth(connection)
|
return self.handle_auth(connection)
|
||||||
|
# When an override flow token exists we actually still use a flow for link
|
||||||
|
# to continue the existing flow we came from
|
||||||
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
||||||
return self._prepare_flow(None, connection)
|
return self._prepare_flow(None, connection)
|
||||||
connection.save()
|
connection.save()
|
||||||
|
@ -67,6 +67,8 @@ def clean_expired_models(self: SystemTask):
|
|||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
"Invalid session_storage setting, allowed values are db and cache"
|
"Invalid session_storage setting, allowed values are db and cache"
|
||||||
)
|
)
|
||||||
|
if CONFIG.get("session_storage", "cache") == "db":
|
||||||
|
DBSessionStore.clear_expired()
|
||||||
LOGGER.debug("Expired sessions", model=AuthenticatedSession, amount=amount)
|
LOGGER.debug("Expired sessions", model=AuthenticatedSession, amount=amount)
|
||||||
|
|
||||||
messages.append(f"Expired {amount} {AuthenticatedSession._meta.verbose_name_plural}")
|
messages.append(f"Expired {amount} {AuthenticatedSession._meta.verbose_name_plural}")
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
{# Darkreader breaks the site regardless of theme as its not compatible with webcomponents, and we default to a dark theme based on preferred colour-scheme #}
|
||||||
|
<meta name="darkreader-lock">
|
||||||
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
||||||
<link rel="icon" href="{{ brand.branding_favicon_url }}">
|
<link rel="icon" href="{{ brand.branding_favicon_url }}">
|
||||||
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
|
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
"""RAC app config"""
|
|
||||||
|
|
||||||
from authentik.enterprise.apps import EnterpriseConfig
|
|
||||||
|
|
||||||
|
|
||||||
class AuthentikEnterpriseProviderRAC(EnterpriseConfig):
|
|
||||||
"""authentik enterprise rac app config"""
|
|
||||||
|
|
||||||
name = "authentik.enterprise.providers.rac"
|
|
||||||
label = "authentik_providers_rac"
|
|
||||||
verbose_name = "authentik Enterprise.Providers.RAC"
|
|
||||||
default = True
|
|
||||||
mountpoint = ""
|
|
||||||
ws_mountpoint = "authentik.enterprise.providers.rac.urls"
|
|
@ -16,7 +16,6 @@ TENANT_APPS = [
|
|||||||
"authentik.enterprise.audit",
|
"authentik.enterprise.audit",
|
||||||
"authentik.enterprise.providers.google_workspace",
|
"authentik.enterprise.providers.google_workspace",
|
||||||
"authentik.enterprise.providers.microsoft_entra",
|
"authentik.enterprise.providers.microsoft_entra",
|
||||||
"authentik.enterprise.providers.rac",
|
|
||||||
"authentik.enterprise.providers.ssf",
|
"authentik.enterprise.providers.ssf",
|
||||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||||
"authentik.enterprise.stages.source",
|
"authentik.enterprise.stages.source",
|
||||||
|
@ -9,13 +9,16 @@ from django.utils.timezone import now
|
|||||||
from guardian.shortcuts import get_anonymous_user
|
from guardian.shortcuts import get_anonymous_user
|
||||||
|
|
||||||
from authentik.core.models import Source, User
|
from authentik.core.models import Source, User
|
||||||
from authentik.core.sources.flow_manager import SESSION_KEY_OVERRIDE_FLOW_TOKEN
|
from authentik.core.sources.flow_manager import (
|
||||||
|
SESSION_KEY_OVERRIDE_FLOW_TOKEN,
|
||||||
|
SESSION_KEY_SOURCE_FLOW_STAGES,
|
||||||
|
)
|
||||||
from authentik.core.types import UILoginButton
|
from authentik.core.types import UILoginButton
|
||||||
from authentik.enterprise.stages.source.models import SourceStage
|
from authentik.enterprise.stages.source.models import SourceStage
|
||||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||||
from authentik.flows.models import FlowToken
|
from authentik.flows.models import FlowToken, in_memory_stage
|
||||||
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED
|
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED
|
||||||
from authentik.flows.stage import ChallengeStageView
|
from authentik.flows.stage import ChallengeStageView, StageView
|
||||||
from authentik.lib.utils.time import timedelta_from_string
|
from authentik.lib.utils.time import timedelta_from_string
|
||||||
|
|
||||||
PLAN_CONTEXT_RESUME_TOKEN = "resume_token" # nosec
|
PLAN_CONTEXT_RESUME_TOKEN = "resume_token" # nosec
|
||||||
@ -49,6 +52,7 @@ class SourceStageView(ChallengeStageView):
|
|||||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||||
resume_token = self.create_flow_token()
|
resume_token = self.create_flow_token()
|
||||||
self.request.session[SESSION_KEY_OVERRIDE_FLOW_TOKEN] = resume_token
|
self.request.session[SESSION_KEY_OVERRIDE_FLOW_TOKEN] = resume_token
|
||||||
|
self.request.session[SESSION_KEY_SOURCE_FLOW_STAGES] = [in_memory_stage(SourceStageFinal)]
|
||||||
return self.login_button.challenge
|
return self.login_button.challenge
|
||||||
|
|
||||||
def create_flow_token(self) -> FlowToken:
|
def create_flow_token(self) -> FlowToken:
|
||||||
@ -77,3 +81,19 @@ class SourceStageView(ChallengeStageView):
|
|||||||
|
|
||||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||||
return self.executor.stage_ok()
|
return self.executor.stage_ok()
|
||||||
|
|
||||||
|
|
||||||
|
class SourceStageFinal(StageView):
|
||||||
|
"""Dynamic stage injected in the source flow manager. This is injected in the
|
||||||
|
flow the source flow manager picks (authentication or enrollment), and will run at the end.
|
||||||
|
This stage uses the override flow token to resume execution of the initial flow the
|
||||||
|
source stage is bound to."""
|
||||||
|
|
||||||
|
def dispatch(self):
|
||||||
|
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
||||||
|
self._logger.info("Replacing source flow with overridden flow", flow=token.flow.slug)
|
||||||
|
plan = token.plan
|
||||||
|
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||||
|
response = plan.to_redirect(self.request, token.flow)
|
||||||
|
token.delete()
|
||||||
|
return response
|
||||||
|
@ -64,6 +64,8 @@ debugger: false
|
|||||||
log_level: info
|
log_level: info
|
||||||
|
|
||||||
session_storage: cache
|
session_storage: cache
|
||||||
|
sessions:
|
||||||
|
unauthenticated_age: days=1
|
||||||
|
|
||||||
error_reporting:
|
error_reporting:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
@ -19,7 +19,6 @@ from authentik.core.api.used_by import UsedByMixin
|
|||||||
from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSerializer
|
from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.enterprise.license import LicenseKey
|
from authentik.enterprise.license import LicenseKey
|
||||||
from authentik.enterprise.providers.rac.models import RACProvider
|
|
||||||
from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
|
from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
|
||||||
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
|
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
|
||||||
from authentik.outposts.apps import MANAGED_OUTPOST, MANAGED_OUTPOST_NAME
|
from authentik.outposts.apps import MANAGED_OUTPOST, MANAGED_OUTPOST_NAME
|
||||||
@ -31,6 +30,7 @@ from authentik.outposts.models import (
|
|||||||
)
|
)
|
||||||
from authentik.providers.ldap.models import LDAPProvider
|
from authentik.providers.ldap.models import LDAPProvider
|
||||||
from authentik.providers.proxy.models import ProxyProvider
|
from authentik.providers.proxy.models import ProxyProvider
|
||||||
|
from authentik.providers.rac.models import RACProvider
|
||||||
from authentik.providers.radius.models import RadiusProvider
|
from authentik.providers.radius.models import RadiusProvider
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION
|
|||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
from yaml import safe_load
|
from yaml import safe_load
|
||||||
|
|
||||||
from authentik.enterprise.providers.rac.controllers.docker import RACDockerController
|
|
||||||
from authentik.enterprise.providers.rac.controllers.kubernetes import RACKubernetesController
|
|
||||||
from authentik.events.models import TaskStatus
|
from authentik.events.models import TaskStatus
|
||||||
from authentik.events.system_tasks import SystemTask, prefill_task
|
from authentik.events.system_tasks import SystemTask, prefill_task
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
@ -41,6 +39,8 @@ from authentik.providers.ldap.controllers.docker import LDAPDockerController
|
|||||||
from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
|
from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
|
||||||
from authentik.providers.proxy.controllers.docker import ProxyDockerController
|
from authentik.providers.proxy.controllers.docker import ProxyDockerController
|
||||||
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
|
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
|
||||||
|
from authentik.providers.rac.controllers.docker import RACDockerController
|
||||||
|
from authentik.providers.rac.controllers.kubernetes import RACKubernetesController
|
||||||
from authentik.providers.radius.controllers.docker import RadiusDockerController
|
from authentik.providers.radius.controllers.docker import RadiusDockerController
|
||||||
from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
|
from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
|
||||||
from authentik.root.celery import CELERY_APP
|
from authentik.root.celery import CELERY_APP
|
||||||
|
@ -128,7 +128,7 @@ class GeoIPPolicy(Policy):
|
|||||||
(geoip_data["lat"], geoip_data["long"]),
|
(geoip_data["lat"], geoip_data["long"]),
|
||||||
)
|
)
|
||||||
if self.check_history_distance and dist.km >= (
|
if self.check_history_distance and dist.km >= (
|
||||||
self.history_max_distance_km - self.distance_tolerance_km
|
self.history_max_distance_km + self.distance_tolerance_km
|
||||||
):
|
):
|
||||||
return PolicyResult(
|
return PolicyResult(
|
||||||
False, _("Distance from previous authentication is larger than threshold.")
|
False, _("Distance from previous authentication is larger than threshold.")
|
||||||
@ -139,7 +139,7 @@ class GeoIPPolicy(Policy):
|
|||||||
# clamped to be at least 1 hour
|
# clamped to be at least 1 hour
|
||||||
rel_time_hours = max(int((_now - previous_login.created).total_seconds() / 3600), 1)
|
rel_time_hours = max(int((_now - previous_login.created).total_seconds() / 3600), 1)
|
||||||
if self.check_impossible_travel and dist.km >= (
|
if self.check_impossible_travel and dist.km >= (
|
||||||
(MAX_DISTANCE_HOUR_KM * rel_time_hours) - self.distance_tolerance_km
|
(MAX_DISTANCE_HOUR_KM * rel_time_hours) + self.distance_tolerance_km
|
||||||
):
|
):
|
||||||
return PolicyResult(False, _("Distance is further than possible."))
|
return PolicyResult(False, _("Distance is further than possible."))
|
||||||
return PolicyResult(True)
|
return PolicyResult(True)
|
||||||
|
@ -148,10 +148,10 @@ class PasswordPolicy(Policy):
|
|||||||
user_inputs.append(request.user.email)
|
user_inputs.append(request.user.email)
|
||||||
if request.http_request:
|
if request.http_request:
|
||||||
user_inputs.append(request.http_request.brand.branding_title)
|
user_inputs.append(request.http_request.brand.branding_title)
|
||||||
# Only calculate result for the first 100 characters, as with over 100 char
|
# Only calculate result for the first 72 characters, as with over 100 char
|
||||||
# long passwords we can be reasonably sure that they'll surpass the score anyways
|
# long passwords we can be reasonably sure that they'll surpass the score anyways
|
||||||
# See https://github.com/dropbox/zxcvbn#runtime-latency
|
# See https://github.com/dropbox/zxcvbn#runtime-latency
|
||||||
results = zxcvbn(password[:100], user_inputs)
|
results = zxcvbn(password[:72], user_inputs)
|
||||||
LOGGER.debug("password failed", check="zxcvbn", score=results["score"])
|
LOGGER.debug("password failed", check="zxcvbn", score=results["score"])
|
||||||
result = PolicyResult(results["score"] > self.zxcvbn_score_threshold)
|
result = PolicyResult(results["score"] > self.zxcvbn_score_threshold)
|
||||||
if not result.passing:
|
if not result.passing:
|
||||||
|
@ -6,13 +6,12 @@ from rest_framework.viewsets import GenericViewSet
|
|||||||
from authentik.core.api.groups import GroupMemberSerializer
|
from authentik.core.api.groups import GroupMemberSerializer
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import ModelSerializer
|
from authentik.core.api.utils import ModelSerializer
|
||||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
from authentik.providers.rac.api.endpoints import EndpointSerializer
|
||||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
|
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
from authentik.providers.rac.models import ConnectionToken
|
||||||
from authentik.enterprise.providers.rac.models import ConnectionToken
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionTokenSerializer(EnterpriseRequiredMixin, ModelSerializer):
|
class ConnectionTokenSerializer(ModelSerializer):
|
||||||
"""ConnectionToken Serializer"""
|
"""ConnectionToken Serializer"""
|
||||||
|
|
||||||
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
@ -14,10 +14,9 @@ from structlog.stdlib import get_logger
|
|||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import ModelSerializer
|
from authentik.core.api.utils import ModelSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
|
||||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
|
||||||
from authentik.enterprise.providers.rac.models import Endpoint
|
|
||||||
from authentik.policies.engine import PolicyEngine
|
from authentik.policies.engine import PolicyEngine
|
||||||
|
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||||
|
from authentik.providers.rac.models import Endpoint
|
||||||
from authentik.rbac.filters import ObjectFilter
|
from authentik.rbac.filters import ObjectFilter
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
@ -28,7 +27,7 @@ def user_endpoint_cache_key(user_pk: str) -> str:
|
|||||||
return f"goauthentik.io/providers/rac/endpoint_access/{user_pk}"
|
return f"goauthentik.io/providers/rac/endpoint_access/{user_pk}"
|
||||||
|
|
||||||
|
|
||||||
class EndpointSerializer(EnterpriseRequiredMixin, ModelSerializer):
|
class EndpointSerializer(ModelSerializer):
|
||||||
"""Endpoint Serializer"""
|
"""Endpoint Serializer"""
|
||||||
|
|
||||||
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
@ -10,7 +10,7 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
from authentik.core.api.property_mappings import PropertyMappingSerializer
|
from authentik.core.api.property_mappings import PropertyMappingSerializer
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import JSONDictField
|
from authentik.core.api.utils import JSONDictField
|
||||||
from authentik.enterprise.providers.rac.models import RACPropertyMapping
|
from authentik.providers.rac.models import RACPropertyMapping
|
||||||
|
|
||||||
|
|
||||||
class RACPropertyMappingSerializer(PropertyMappingSerializer):
|
class RACPropertyMappingSerializer(PropertyMappingSerializer):
|
@ -5,11 +5,10 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
|
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
from authentik.core.api.providers import ProviderSerializer
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
from authentik.providers.rac.models import RACProvider
|
||||||
from authentik.enterprise.providers.rac.models import RACProvider
|
|
||||||
|
|
||||||
|
|
||||||
class RACProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
|
class RACProviderSerializer(ProviderSerializer):
|
||||||
"""RACProvider Serializer"""
|
"""RACProvider Serializer"""
|
||||||
|
|
||||||
outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
|
outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
|
14
authentik/providers/rac/apps.py
Normal file
14
authentik/providers/rac/apps.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"""RAC app config"""
|
||||||
|
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class AuthentikProviderRAC(AppConfig):
|
||||||
|
"""authentik rac app config"""
|
||||||
|
|
||||||
|
name = "authentik.providers.rac"
|
||||||
|
label = "authentik_providers_rac"
|
||||||
|
verbose_name = "authentik Providers.RAC"
|
||||||
|
default = True
|
||||||
|
mountpoint = ""
|
||||||
|
ws_mountpoint = "authentik.providers.rac.urls"
|
@ -7,22 +7,22 @@ from channels.generic.websocket import AsyncWebsocketConsumer
|
|||||||
from django.http.request import QueryDict
|
from django.http.request import QueryDict
|
||||||
from structlog.stdlib import BoundLogger, get_logger
|
from structlog.stdlib import BoundLogger, get_logger
|
||||||
|
|
||||||
from authentik.enterprise.providers.rac.models import ConnectionToken, RACProvider
|
|
||||||
from authentik.outposts.consumer import OUTPOST_GROUP_INSTANCE
|
from authentik.outposts.consumer import OUTPOST_GROUP_INSTANCE
|
||||||
from authentik.outposts.models import Outpost, OutpostState, OutpostType
|
from authentik.outposts.models import Outpost, OutpostState, OutpostType
|
||||||
|
from authentik.providers.rac.models import ConnectionToken, RACProvider
|
||||||
|
|
||||||
# Global broadcast group, which messages are sent to when the outpost connects back
|
# Global broadcast group, which messages are sent to when the outpost connects back
|
||||||
# to authentik for a specific connection
|
# to authentik for a specific connection
|
||||||
# The `RACClientConsumer` consumer adds itself to this group on connection,
|
# The `RACClientConsumer` consumer adds itself to this group on connection,
|
||||||
# and removes itself once it has been assigned a specific outpost channel
|
# and removes itself once it has been assigned a specific outpost channel
|
||||||
RAC_CLIENT_GROUP = "group_enterprise_rac_client"
|
RAC_CLIENT_GROUP = "group_rac_client"
|
||||||
# A group for all connections in a given authentik session ID
|
# A group for all connections in a given authentik session ID
|
||||||
# A disconnect message is sent to this group when the session expires/is deleted
|
# A disconnect message is sent to this group when the session expires/is deleted
|
||||||
RAC_CLIENT_GROUP_SESSION = "group_enterprise_rac_client_%(session)s"
|
RAC_CLIENT_GROUP_SESSION = "group_rac_client_%(session)s"
|
||||||
# A group for all connections with a specific token, which in almost all cases
|
# A group for all connections with a specific token, which in almost all cases
|
||||||
# is just one connection, however this is used to disconnect the connection
|
# is just one connection, however this is used to disconnect the connection
|
||||||
# when the token is deleted
|
# when the token is deleted
|
||||||
RAC_CLIENT_GROUP_TOKEN = "group_enterprise_rac_token_%(token)s" # nosec
|
RAC_CLIENT_GROUP_TOKEN = "group_rac_token_%(token)s" # nosec
|
||||||
|
|
||||||
# Step 1: Client connects to this websocket endpoint
|
# Step 1: Client connects to this websocket endpoint
|
||||||
# Step 2: We prepare all the connection args for Guac
|
# Step 2: We prepare all the connection args for Guac
|
@ -3,7 +3,7 @@
|
|||||||
from channels.exceptions import ChannelFull
|
from channels.exceptions import ChannelFull
|
||||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||||
|
|
||||||
from authentik.enterprise.providers.rac.consumer_client import RAC_CLIENT_GROUP
|
from authentik.providers.rac.consumer_client import RAC_CLIENT_GROUP
|
||||||
|
|
||||||
|
|
||||||
class RACOutpostConsumer(AsyncWebsocketConsumer):
|
class RACOutpostConsumer(AsyncWebsocketConsumer):
|
@ -74,7 +74,7 @@ class RACProvider(Provider):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> type[Serializer]:
|
def serializer(self) -> type[Serializer]:
|
||||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||||
|
|
||||||
return RACProviderSerializer
|
return RACProviderSerializer
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ class Endpoint(SerializerModel, PolicyBindingModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> type[Serializer]:
|
def serializer(self) -> type[Serializer]:
|
||||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
|
from authentik.providers.rac.api.endpoints import EndpointSerializer
|
||||||
|
|
||||||
return EndpointSerializer
|
return EndpointSerializer
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ class RACPropertyMapping(PropertyMapping):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> type[Serializer]:
|
def serializer(self) -> type[Serializer]:
|
||||||
from authentik.enterprise.providers.rac.api.property_mappings import (
|
from authentik.providers.rac.api.property_mappings import (
|
||||||
RACPropertyMappingSerializer,
|
RACPropertyMappingSerializer,
|
||||||
)
|
)
|
||||||
|
|
@ -10,12 +10,12 @@ from django.dispatch import receiver
|
|||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.enterprise.providers.rac.api.endpoints import user_endpoint_cache_key
|
from authentik.providers.rac.api.endpoints import user_endpoint_cache_key
|
||||||
from authentik.enterprise.providers.rac.consumer_client import (
|
from authentik.providers.rac.consumer_client import (
|
||||||
RAC_CLIENT_GROUP_SESSION,
|
RAC_CLIENT_GROUP_SESSION,
|
||||||
RAC_CLIENT_GROUP_TOKEN,
|
RAC_CLIENT_GROUP_TOKEN,
|
||||||
)
|
)
|
||||||
from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint
|
from authentik.providers.rac.models import ConnectionToken, Endpoint
|
||||||
|
|
||||||
|
|
||||||
@receiver(user_logged_out)
|
@receiver(user_logged_out)
|
@ -3,7 +3,7 @@
|
|||||||
{% load authentik_core %}
|
{% load authentik_core %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% versioned_script 'dist/enterprise/rac/index-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/rac/index-%v.js' %}" type="module"></script>
|
||||||
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
|
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
|
||||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
||||||
<link rel="icon" href="{{ tenant.branding_favicon_url }}">
|
<link rel="icon" href="{{ tenant.branding_favicon_url }}">
|
@ -1,16 +1,9 @@
|
|||||||
"""Test RAC Provider"""
|
"""Test RAC Provider"""
|
||||||
|
|
||||||
from datetime import timedelta
|
|
||||||
from time import mktime
|
|
||||||
from unittest.mock import MagicMock, patch
|
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.timezone import now
|
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||||
from authentik.enterprise.license import LicenseKey
|
|
||||||
from authentik.enterprise.models import License
|
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
|
|
||||||
|
|
||||||
@ -20,21 +13,8 @@ class TestAPI(APITestCase):
|
|||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
self.user = create_test_admin_user()
|
self.user = create_test_admin_user()
|
||||||
|
|
||||||
@patch(
|
|
||||||
"authentik.enterprise.license.LicenseKey.validate",
|
|
||||||
MagicMock(
|
|
||||||
return_value=LicenseKey(
|
|
||||||
aud="",
|
|
||||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
|
||||||
name=generate_id(),
|
|
||||||
internal_users=100,
|
|
||||||
external_users=100,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
"""Test creation of RAC Provider"""
|
"""Test creation of RAC Provider"""
|
||||||
License.objects.create(key=generate_id())
|
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("authentik_api:racprovider-list"),
|
reverse("authentik_api:racprovider-list"),
|
@ -5,10 +5,10 @@ from rest_framework.test import APITestCase
|
|||||||
|
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
from authentik.core.tests.utils import create_test_admin_user
|
from authentik.core.tests.utils import create_test_admin_user
|
||||||
from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
|
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
from authentik.policies.dummy.models import DummyPolicy
|
from authentik.policies.dummy.models import DummyPolicy
|
||||||
from authentik.policies.models import PolicyBinding
|
from authentik.policies.models import PolicyBinding
|
||||||
|
from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||||
|
|
||||||
|
|
||||||
class TestEndpointsAPI(APITestCase):
|
class TestEndpointsAPI(APITestCase):
|
@ -4,14 +4,14 @@ from django.test import TransactionTestCase
|
|||||||
|
|
||||||
from authentik.core.models import Application, AuthenticatedSession
|
from authentik.core.models import Application, AuthenticatedSession
|
||||||
from authentik.core.tests.utils import create_test_admin_user
|
from authentik.core.tests.utils import create_test_admin_user
|
||||||
from authentik.enterprise.providers.rac.models import (
|
from authentik.lib.generators import generate_id
|
||||||
|
from authentik.providers.rac.models import (
|
||||||
ConnectionToken,
|
ConnectionToken,
|
||||||
Endpoint,
|
Endpoint,
|
||||||
Protocols,
|
Protocols,
|
||||||
RACPropertyMapping,
|
RACPropertyMapping,
|
||||||
RACProvider,
|
RACProvider,
|
||||||
)
|
)
|
||||||
from authentik.lib.generators import generate_id
|
|
||||||
|
|
||||||
|
|
||||||
class TestModels(TransactionTestCase):
|
class TestModels(TransactionTestCase):
|
@ -1,23 +1,17 @@
|
|||||||
"""RAC Views tests"""
|
"""RAC Views tests"""
|
||||||
|
|
||||||
from datetime import timedelta
|
|
||||||
from json import loads
|
from json import loads
|
||||||
from time import mktime
|
|
||||||
from unittest.mock import MagicMock, patch
|
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.timezone import now
|
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||||
from authentik.enterprise.license import LicenseKey
|
|
||||||
from authentik.enterprise.models import License
|
|
||||||
from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
|
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
from authentik.policies.denied import AccessDeniedResponse
|
from authentik.policies.denied import AccessDeniedResponse
|
||||||
from authentik.policies.dummy.models import DummyPolicy
|
from authentik.policies.dummy.models import DummyPolicy
|
||||||
from authentik.policies.models import PolicyBinding
|
from authentik.policies.models import PolicyBinding
|
||||||
|
from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||||
|
|
||||||
|
|
||||||
class TestRACViews(APITestCase):
|
class TestRACViews(APITestCase):
|
||||||
@ -39,21 +33,8 @@ class TestRACViews(APITestCase):
|
|||||||
provider=self.provider,
|
provider=self.provider,
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch(
|
|
||||||
"authentik.enterprise.license.LicenseKey.validate",
|
|
||||||
MagicMock(
|
|
||||||
return_value=LicenseKey(
|
|
||||||
aud="",
|
|
||||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
|
||||||
name=generate_id(),
|
|
||||||
internal_users=100,
|
|
||||||
external_users=100,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_no_policy(self):
|
def test_no_policy(self):
|
||||||
"""Test request"""
|
"""Test request"""
|
||||||
License.objects.create(key=generate_id())
|
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse(
|
reverse(
|
||||||
@ -70,18 +51,6 @@ class TestRACViews(APITestCase):
|
|||||||
final_response = self.client.get(next_url)
|
final_response = self.client.get(next_url)
|
||||||
self.assertEqual(final_response.status_code, 200)
|
self.assertEqual(final_response.status_code, 200)
|
||||||
|
|
||||||
@patch(
|
|
||||||
"authentik.enterprise.license.LicenseKey.validate",
|
|
||||||
MagicMock(
|
|
||||||
return_value=LicenseKey(
|
|
||||||
aud="",
|
|
||||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
|
||||||
name=generate_id(),
|
|
||||||
internal_users=100,
|
|
||||||
external_users=100,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_app_deny(self):
|
def test_app_deny(self):
|
||||||
"""Test request (deny on app level)"""
|
"""Test request (deny on app level)"""
|
||||||
PolicyBinding.objects.create(
|
PolicyBinding.objects.create(
|
||||||
@ -89,7 +58,6 @@ class TestRACViews(APITestCase):
|
|||||||
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
||||||
order=0,
|
order=0,
|
||||||
)
|
)
|
||||||
License.objects.create(key=generate_id())
|
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse(
|
reverse(
|
||||||
@ -99,18 +67,6 @@ class TestRACViews(APITestCase):
|
|||||||
)
|
)
|
||||||
self.assertIsInstance(response, AccessDeniedResponse)
|
self.assertIsInstance(response, AccessDeniedResponse)
|
||||||
|
|
||||||
@patch(
|
|
||||||
"authentik.enterprise.license.LicenseKey.validate",
|
|
||||||
MagicMock(
|
|
||||||
return_value=LicenseKey(
|
|
||||||
aud="",
|
|
||||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
|
||||||
name=generate_id(),
|
|
||||||
internal_users=100,
|
|
||||||
external_users=100,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_endpoint_deny(self):
|
def test_endpoint_deny(self):
|
||||||
"""Test request (deny on endpoint level)"""
|
"""Test request (deny on endpoint level)"""
|
||||||
PolicyBinding.objects.create(
|
PolicyBinding.objects.create(
|
||||||
@ -118,7 +74,6 @@ class TestRACViews(APITestCase):
|
|||||||
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
||||||
order=0,
|
order=0,
|
||||||
)
|
)
|
||||||
License.objects.create(key=generate_id())
|
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse(
|
reverse(
|
@ -4,14 +4,14 @@ from channels.auth import AuthMiddleware
|
|||||||
from channels.sessions import CookieMiddleware
|
from channels.sessions import CookieMiddleware
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from authentik.enterprise.providers.rac.api.connection_tokens import ConnectionTokenViewSet
|
|
||||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointViewSet
|
|
||||||
from authentik.enterprise.providers.rac.api.property_mappings import RACPropertyMappingViewSet
|
|
||||||
from authentik.enterprise.providers.rac.api.providers import RACProviderViewSet
|
|
||||||
from authentik.enterprise.providers.rac.consumer_client import RACClientConsumer
|
|
||||||
from authentik.enterprise.providers.rac.consumer_outpost import RACOutpostConsumer
|
|
||||||
from authentik.enterprise.providers.rac.views import RACInterface, RACStartView
|
|
||||||
from authentik.outposts.channels import TokenOutpostMiddleware
|
from authentik.outposts.channels import TokenOutpostMiddleware
|
||||||
|
from authentik.providers.rac.api.connection_tokens import ConnectionTokenViewSet
|
||||||
|
from authentik.providers.rac.api.endpoints import EndpointViewSet
|
||||||
|
from authentik.providers.rac.api.property_mappings import RACPropertyMappingViewSet
|
||||||
|
from authentik.providers.rac.api.providers import RACProviderViewSet
|
||||||
|
from authentik.providers.rac.consumer_client import RACClientConsumer
|
||||||
|
from authentik.providers.rac.consumer_outpost import RACOutpostConsumer
|
||||||
|
from authentik.providers.rac.views import RACInterface, RACStartView
|
||||||
from authentik.root.asgi_middleware import SessionMiddleware
|
from authentik.root.asgi_middleware import SessionMiddleware
|
||||||
from authentik.root.middleware import ChannelsLoggingMiddleware
|
from authentik.root.middleware import ChannelsLoggingMiddleware
|
||||||
|
|
@ -10,8 +10,6 @@ from django.utils.translation import gettext as _
|
|||||||
|
|
||||||
from authentik.core.models import Application, AuthenticatedSession
|
from authentik.core.models import Application, AuthenticatedSession
|
||||||
from authentik.core.views.interface import InterfaceView
|
from authentik.core.views.interface import InterfaceView
|
||||||
from authentik.enterprise.policy import EnterprisePolicyAccessView
|
|
||||||
from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint, RACProvider
|
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
from authentik.flows.challenge import RedirectChallenge
|
from authentik.flows.challenge import RedirectChallenge
|
||||||
from authentik.flows.exceptions import FlowNonApplicableException
|
from authentik.flows.exceptions import FlowNonApplicableException
|
||||||
@ -20,9 +18,11 @@ from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
|
|||||||
from authentik.flows.stage import RedirectStage
|
from authentik.flows.stage import RedirectStage
|
||||||
from authentik.lib.utils.time import timedelta_from_string
|
from authentik.lib.utils.time import timedelta_from_string
|
||||||
from authentik.policies.engine import PolicyEngine
|
from authentik.policies.engine import PolicyEngine
|
||||||
|
from authentik.policies.views import PolicyAccessView
|
||||||
|
from authentik.providers.rac.models import ConnectionToken, Endpoint, RACProvider
|
||||||
|
|
||||||
|
|
||||||
class RACStartView(EnterprisePolicyAccessView):
|
class RACStartView(PolicyAccessView):
|
||||||
"""Start a RAC connection by checking access and creating a connection token"""
|
"""Start a RAC connection by checking access and creating a connection token"""
|
||||||
|
|
||||||
endpoint: Endpoint
|
endpoint: Endpoint
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.db.models import Q, QuerySet
|
from django.db.models import QuerySet
|
||||||
from django_filters.filters import ModelChoiceFilter
|
from django_filters.filters import ModelChoiceFilter
|
||||||
from django_filters.filterset import FilterSet
|
from django_filters.filterset import FilterSet
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
@ -18,7 +18,6 @@ from rest_framework.filters import OrderingFilter, SearchFilter
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.blueprints.v1.importer import excluded_models
|
|
||||||
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.lib.validators import RequiredTogetherValidator
|
from authentik.lib.validators import RequiredTogetherValidator
|
||||||
@ -106,13 +105,13 @@ class RBACPermissionViewSet(ReadOnlyModelViewSet):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def get_queryset(self) -> QuerySet:
|
def get_queryset(self) -> QuerySet:
|
||||||
query = Q()
|
return (
|
||||||
for model in excluded_models():
|
Permission.objects.all()
|
||||||
query |= Q(
|
.select_related("content_type")
|
||||||
content_type__app_label=model._meta.app_label,
|
.filter(
|
||||||
content_type__model=model._meta.model_name,
|
content_type__app_label__startswith="authentik",
|
||||||
)
|
)
|
||||||
return Permission.objects.all().select_related("content_type").exclude(query)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PermissionAssignSerializer(PassiveSerializer):
|
class PermissionAssignSerializer(PassiveSerializer):
|
||||||
|
@ -16,6 +16,7 @@ from authentik.lib.config import CONFIG, django_db_config, redis_url
|
|||||||
from authentik.lib.logging import get_logger_config, structlog_configure
|
from authentik.lib.logging import get_logger_config, structlog_configure
|
||||||
from authentik.lib.sentry import sentry_init
|
from authentik.lib.sentry import sentry_init
|
||||||
from authentik.lib.utils.reflection import get_env
|
from authentik.lib.utils.reflection import get_env
|
||||||
|
from authentik.lib.utils.time import timedelta_from_string
|
||||||
from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP
|
from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP
|
||||||
|
|
||||||
BASE_DIR = Path(__file__).absolute().parent.parent.parent
|
BASE_DIR = Path(__file__).absolute().parent.parent.parent
|
||||||
@ -87,6 +88,7 @@ TENANT_APPS = [
|
|||||||
"authentik.providers.ldap",
|
"authentik.providers.ldap",
|
||||||
"authentik.providers.oauth2",
|
"authentik.providers.oauth2",
|
||||||
"authentik.providers.proxy",
|
"authentik.providers.proxy",
|
||||||
|
"authentik.providers.rac",
|
||||||
"authentik.providers.radius",
|
"authentik.providers.radius",
|
||||||
"authentik.providers.saml",
|
"authentik.providers.saml",
|
||||||
"authentik.providers.scim",
|
"authentik.providers.scim",
|
||||||
@ -241,6 +243,9 @@ SESSION_CACHE_ALIAS = "default"
|
|||||||
# Configured via custom SessionMiddleware
|
# Configured via custom SessionMiddleware
|
||||||
# SESSION_COOKIE_SAMESITE = "None"
|
# SESSION_COOKIE_SAMESITE = "None"
|
||||||
# SESSION_COOKIE_SECURE = True
|
# SESSION_COOKIE_SECURE = True
|
||||||
|
SESSION_COOKIE_AGE = timedelta_from_string(
|
||||||
|
CONFIG.get("sessions.unauthenticated_age", "days=1")
|
||||||
|
).total_seconds()
|
||||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
||||||
|
|
||||||
MESSAGE_STORAGE = "authentik.root.messages.storage.ChannelsStorage"
|
MESSAGE_STORAGE = "authentik.root.messages.storage.ChannelsStorage"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from requests import RequestException
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient
|
from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient
|
||||||
@ -21,10 +22,35 @@ class AzureADOAuthRedirect(OAuthRedirect):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AzureADClient(UserprofileHeaderAuthClient):
|
||||||
|
"""Fetch AzureAD group information"""
|
||||||
|
|
||||||
|
def get_profile_info(self, token):
|
||||||
|
profile_data = super().get_profile_info(token)
|
||||||
|
if "https://graph.microsoft.com/GroupMember.Read.All" not in self.source.additional_scopes:
|
||||||
|
return profile_data
|
||||||
|
group_response = self.session.request(
|
||||||
|
"get",
|
||||||
|
"https://graph.microsoft.com/v1.0/me/memberOf",
|
||||||
|
headers={"Authorization": f"{token['token_type']} {token['access_token']}"},
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
group_response.raise_for_status()
|
||||||
|
except RequestException as exc:
|
||||||
|
LOGGER.warning(
|
||||||
|
"Unable to fetch user profile",
|
||||||
|
exc=exc,
|
||||||
|
response=exc.response.text if exc.response else str(exc),
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
profile_data["raw_groups"] = group_response.json()
|
||||||
|
return profile_data
|
||||||
|
|
||||||
|
|
||||||
class AzureADOAuthCallback(OpenIDConnectOAuth2Callback):
|
class AzureADOAuthCallback(OpenIDConnectOAuth2Callback):
|
||||||
"""AzureAD OAuth2 Callback"""
|
"""AzureAD OAuth2 Callback"""
|
||||||
|
|
||||||
client_class = UserprofileHeaderAuthClient
|
client_class = AzureADClient
|
||||||
|
|
||||||
def get_user_id(self, info: dict[str, str]) -> str:
|
def get_user_id(self, info: dict[str, str]) -> str:
|
||||||
# Default try to get `id` for the Graph API endpoint
|
# Default try to get `id` for the Graph API endpoint
|
||||||
@ -53,8 +79,24 @@ class AzureADType(SourceType):
|
|||||||
|
|
||||||
def get_base_user_properties(self, info: dict[str, Any], **kwargs) -> dict[str, Any]:
|
def get_base_user_properties(self, info: dict[str, Any], **kwargs) -> dict[str, Any]:
|
||||||
mail = info.get("mail", None) or info.get("otherMails", [None])[0]
|
mail = info.get("mail", None) or info.get("otherMails", [None])[0]
|
||||||
|
# Format group info
|
||||||
|
groups = []
|
||||||
|
group_id_dict = {}
|
||||||
|
for group in info.get("raw_groups", {}).get("value", []):
|
||||||
|
if group["@odata.type"] != "#microsoft.graph.group":
|
||||||
|
continue
|
||||||
|
groups.append(group["id"])
|
||||||
|
group_id_dict[group["id"]] = group
|
||||||
|
info["raw_groups"] = group_id_dict
|
||||||
return {
|
return {
|
||||||
"username": info.get("userPrincipalName"),
|
"username": info.get("userPrincipalName"),
|
||||||
"email": mail,
|
"email": mail,
|
||||||
"name": info.get("displayName"),
|
"name": info.get("displayName"),
|
||||||
|
"groups": groups,
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_base_group_properties(self, source, group_id, **kwargs):
|
||||||
|
raw_group = kwargs["info"]["raw_groups"][group_id]
|
||||||
|
return {
|
||||||
|
"name": raw_group["displayName"],
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"$schema": "http://json-schema.org/draft-07/schema",
|
"$schema": "http://json-schema.org/draft-07/schema",
|
||||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "authentik 2024.12.3 Blueprint schema",
|
"title": "authentik 2025.2.0 Blueprint schema",
|
||||||
"required": [
|
"required": [
|
||||||
"version",
|
"version",
|
||||||
"entries"
|
"entries"
|
||||||
@ -801,6 +801,126 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"model",
|
||||||
|
"identifiers"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"const": "authentik_providers_rac.racprovider"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"absent",
|
||||||
|
"present",
|
||||||
|
"created",
|
||||||
|
"must_created"
|
||||||
|
],
|
||||||
|
"default": "present"
|
||||||
|
},
|
||||||
|
"conditions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||||
|
},
|
||||||
|
"identifiers": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"model",
|
||||||
|
"identifiers"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"const": "authentik_providers_rac.endpoint"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"absent",
|
||||||
|
"present",
|
||||||
|
"created",
|
||||||
|
"must_created"
|
||||||
|
],
|
||||||
|
"default": "present"
|
||||||
|
},
|
||||||
|
"conditions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||||
|
},
|
||||||
|
"identifiers": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"model",
|
||||||
|
"identifiers"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"const": "authentik_providers_rac.racpropertymapping"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"absent",
|
||||||
|
"present",
|
||||||
|
"created",
|
||||||
|
"must_created"
|
||||||
|
],
|
||||||
|
"default": "present"
|
||||||
|
},
|
||||||
|
"conditions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||||
|
},
|
||||||
|
"identifiers": {
|
||||||
|
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -3561,126 +3681,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"model",
|
|
||||||
"identifiers"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"const": "authentik_providers_rac.racprovider"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"absent",
|
|
||||||
"present",
|
|
||||||
"created",
|
|
||||||
"must_created"
|
|
||||||
],
|
|
||||||
"default": "present"
|
|
||||||
},
|
|
||||||
"conditions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
|
|
||||||
},
|
|
||||||
"attrs": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
|
||||||
},
|
|
||||||
"identifiers": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"model",
|
|
||||||
"identifiers"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"const": "authentik_providers_rac.endpoint"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"absent",
|
|
||||||
"present",
|
|
||||||
"created",
|
|
||||||
"must_created"
|
|
||||||
],
|
|
||||||
"default": "present"
|
|
||||||
},
|
|
||||||
"conditions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
|
|
||||||
},
|
|
||||||
"attrs": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
|
||||||
},
|
|
||||||
"identifiers": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"model",
|
|
||||||
"identifiers"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"const": "authentik_providers_rac.racpropertymapping"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"absent",
|
|
||||||
"present",
|
|
||||||
"created",
|
|
||||||
"must_created"
|
|
||||||
],
|
|
||||||
"default": "present"
|
|
||||||
},
|
|
||||||
"conditions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
|
|
||||||
},
|
|
||||||
"attrs": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
|
||||||
},
|
|
||||||
"identifiers": {
|
|
||||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -4663,6 +4663,7 @@
|
|||||||
"authentik.providers.ldap",
|
"authentik.providers.ldap",
|
||||||
"authentik.providers.oauth2",
|
"authentik.providers.oauth2",
|
||||||
"authentik.providers.proxy",
|
"authentik.providers.proxy",
|
||||||
|
"authentik.providers.rac",
|
||||||
"authentik.providers.radius",
|
"authentik.providers.radius",
|
||||||
"authentik.providers.saml",
|
"authentik.providers.saml",
|
||||||
"authentik.providers.scim",
|
"authentik.providers.scim",
|
||||||
@ -4703,7 +4704,6 @@
|
|||||||
"authentik.enterprise.audit",
|
"authentik.enterprise.audit",
|
||||||
"authentik.enterprise.providers.google_workspace",
|
"authentik.enterprise.providers.google_workspace",
|
||||||
"authentik.enterprise.providers.microsoft_entra",
|
"authentik.enterprise.providers.microsoft_entra",
|
||||||
"authentik.enterprise.providers.rac",
|
|
||||||
"authentik.enterprise.providers.ssf",
|
"authentik.enterprise.providers.ssf",
|
||||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||||
"authentik.enterprise.stages.source",
|
"authentik.enterprise.stages.source",
|
||||||
@ -4738,6 +4738,9 @@
|
|||||||
"authentik_providers_oauth2.scopemapping",
|
"authentik_providers_oauth2.scopemapping",
|
||||||
"authentik_providers_oauth2.oauth2provider",
|
"authentik_providers_oauth2.oauth2provider",
|
||||||
"authentik_providers_proxy.proxyprovider",
|
"authentik_providers_proxy.proxyprovider",
|
||||||
|
"authentik_providers_rac.racprovider",
|
||||||
|
"authentik_providers_rac.endpoint",
|
||||||
|
"authentik_providers_rac.racpropertymapping",
|
||||||
"authentik_providers_radius.radiusprovider",
|
"authentik_providers_radius.radiusprovider",
|
||||||
"authentik_providers_radius.radiusproviderpropertymapping",
|
"authentik_providers_radius.radiusproviderpropertymapping",
|
||||||
"authentik_providers_saml.samlprovider",
|
"authentik_providers_saml.samlprovider",
|
||||||
@ -4807,9 +4810,6 @@
|
|||||||
"authentik_providers_google_workspace.googleworkspaceprovidermapping",
|
"authentik_providers_google_workspace.googleworkspaceprovidermapping",
|
||||||
"authentik_providers_microsoft_entra.microsoftentraprovider",
|
"authentik_providers_microsoft_entra.microsoftentraprovider",
|
||||||
"authentik_providers_microsoft_entra.microsoftentraprovidermapping",
|
"authentik_providers_microsoft_entra.microsoftentraprovidermapping",
|
||||||
"authentik_providers_rac.racprovider",
|
|
||||||
"authentik_providers_rac.endpoint",
|
|
||||||
"authentik_providers_rac.racpropertymapping",
|
|
||||||
"authentik_providers_ssf.ssfprovider",
|
"authentik_providers_ssf.ssfprovider",
|
||||||
"authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
|
"authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
|
||||||
"authentik_stages_source.sourcestage",
|
"authentik_stages_source.sourcestage",
|
||||||
@ -6046,6 +6046,216 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"model_authentik_providers_rac.racprovider": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Name"
|
||||||
|
},
|
||||||
|
"authentication_flow": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid",
|
||||||
|
"title": "Authentication flow",
|
||||||
|
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||||
|
},
|
||||||
|
"authorization_flow": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid",
|
||||||
|
"title": "Authorization flow",
|
||||||
|
"description": "Flow used when authorizing this provider."
|
||||||
|
},
|
||||||
|
"property_mappings": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
},
|
||||||
|
"title": "Property mappings"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Settings"
|
||||||
|
},
|
||||||
|
"connection_expiry": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Connection expiry",
|
||||||
|
"description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||||
|
},
|
||||||
|
"delete_token_on_disconnect": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Delete token on disconnect",
|
||||||
|
"description": "When set to true, connection tokens will be deleted upon disconnect."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"model_authentik_providers_rac.racprovider_permissions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"permission"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"permission": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"add_racprovider",
|
||||||
|
"change_racprovider",
|
||||||
|
"delete_racprovider",
|
||||||
|
"view_racprovider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"model_authentik_providers_rac.endpoint": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Name"
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"type": "integer",
|
||||||
|
"title": "Provider"
|
||||||
|
},
|
||||||
|
"protocol": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"rdp",
|
||||||
|
"vnc",
|
||||||
|
"ssh"
|
||||||
|
],
|
||||||
|
"title": "Protocol"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Host"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Settings"
|
||||||
|
},
|
||||||
|
"property_mappings": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
},
|
||||||
|
"title": "Property mappings"
|
||||||
|
},
|
||||||
|
"auth_mode": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"static",
|
||||||
|
"prompt"
|
||||||
|
],
|
||||||
|
"title": "Auth mode"
|
||||||
|
},
|
||||||
|
"maximum_connections": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -2147483648,
|
||||||
|
"maximum": 2147483647,
|
||||||
|
"title": "Maximum connections"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"model_authentik_providers_rac.endpoint_permissions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"permission"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"permission": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"add_endpoint",
|
||||||
|
"change_endpoint",
|
||||||
|
"delete_endpoint",
|
||||||
|
"view_endpoint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"model_authentik_providers_rac.racpropertymapping": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"managed": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Managed by authentik",
|
||||||
|
"description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Name"
|
||||||
|
},
|
||||||
|
"expression": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Expression"
|
||||||
|
},
|
||||||
|
"static_settings": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Static settings"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"model_authentik_providers_rac.racpropertymapping_permissions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"permission"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"permission": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"add_racpropertymapping",
|
||||||
|
"change_racpropertymapping",
|
||||||
|
"delete_racpropertymapping",
|
||||||
|
"view_racpropertymapping"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model_authentik_providers_radius.radiusprovider": {
|
"model_authentik_providers_radius.radiusprovider": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -14215,216 +14425,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"model_authentik_providers_rac.racprovider": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Name"
|
|
||||||
},
|
|
||||||
"authentication_flow": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid",
|
|
||||||
"title": "Authentication flow",
|
|
||||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
|
||||||
},
|
|
||||||
"authorization_flow": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid",
|
|
||||||
"title": "Authorization flow",
|
|
||||||
"description": "Flow used when authorizing this provider."
|
|
||||||
},
|
|
||||||
"property_mappings": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid"
|
|
||||||
},
|
|
||||||
"title": "Property mappings"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true,
|
|
||||||
"title": "Settings"
|
|
||||||
},
|
|
||||||
"connection_expiry": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Connection expiry",
|
|
||||||
"description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
|
||||||
},
|
|
||||||
"delete_token_on_disconnect": {
|
|
||||||
"type": "boolean",
|
|
||||||
"title": "Delete token on disconnect",
|
|
||||||
"description": "When set to true, connection tokens will be deleted upon disconnect."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": []
|
|
||||||
},
|
|
||||||
"model_authentik_providers_rac.racprovider_permissions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"permission"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"permission": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"add_racprovider",
|
|
||||||
"change_racprovider",
|
|
||||||
"delete_racprovider",
|
|
||||||
"view_racprovider"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"model_authentik_providers_rac.endpoint": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Name"
|
|
||||||
},
|
|
||||||
"provider": {
|
|
||||||
"type": "integer",
|
|
||||||
"title": "Provider"
|
|
||||||
},
|
|
||||||
"protocol": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"rdp",
|
|
||||||
"vnc",
|
|
||||||
"ssh"
|
|
||||||
],
|
|
||||||
"title": "Protocol"
|
|
||||||
},
|
|
||||||
"host": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Host"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true,
|
|
||||||
"title": "Settings"
|
|
||||||
},
|
|
||||||
"property_mappings": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid"
|
|
||||||
},
|
|
||||||
"title": "Property mappings"
|
|
||||||
},
|
|
||||||
"auth_mode": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"static",
|
|
||||||
"prompt"
|
|
||||||
],
|
|
||||||
"title": "Auth mode"
|
|
||||||
},
|
|
||||||
"maximum_connections": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": -2147483648,
|
|
||||||
"maximum": 2147483647,
|
|
||||||
"title": "Maximum connections"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": []
|
|
||||||
},
|
|
||||||
"model_authentik_providers_rac.endpoint_permissions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"permission"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"permission": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"add_endpoint",
|
|
||||||
"change_endpoint",
|
|
||||||
"delete_endpoint",
|
|
||||||
"view_endpoint"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"model_authentik_providers_rac.racpropertymapping": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"managed": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Managed by authentik",
|
|
||||||
"description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"title": "Name"
|
|
||||||
},
|
|
||||||
"expression": {
|
|
||||||
"type": "string",
|
|
||||||
"title": "Expression"
|
|
||||||
},
|
|
||||||
"static_settings": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true,
|
|
||||||
"title": "Static settings"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": []
|
|
||||||
},
|
|
||||||
"model_authentik_providers_rac.racpropertymapping_permissions": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"permission"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"permission": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"add_racpropertymapping",
|
|
||||||
"change_racpropertymapping",
|
|
||||||
"delete_racpropertymapping",
|
|
||||||
"view_racpropertymapping"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"model_authentik_providers_ssf.ssfprovider": {
|
"model_authentik_providers_ssf.ssfprovider": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"goauthentik.io/internal/common"
|
"goauthentik.io/internal/common"
|
||||||
"goauthentik.io/internal/config"
|
"goauthentik.io/internal/config"
|
||||||
|
"goauthentik.io/internal/constants"
|
||||||
"goauthentik.io/internal/debug"
|
"goauthentik.io/internal/debug"
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||||
@ -24,7 +25,8 @@ Required environment variables:
|
|||||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Long: helpMessage,
|
Long: helpMessage,
|
||||||
|
Version: constants.FullVersion(),
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"goauthentik.io/internal/common"
|
"goauthentik.io/internal/common"
|
||||||
"goauthentik.io/internal/config"
|
"goauthentik.io/internal/config"
|
||||||
|
"goauthentik.io/internal/constants"
|
||||||
"goauthentik.io/internal/debug"
|
"goauthentik.io/internal/debug"
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||||
@ -27,7 +28,8 @@ Optionally, you can set these:
|
|||||||
- AUTHENTIK_HOST_BROWSER: URL to use in the browser, when it differs from AUTHENTIK_HOST`
|
- AUTHENTIK_HOST_BROWSER: URL to use in the browser, when it differs from AUTHENTIK_HOST`
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Long: helpMessage,
|
Long: helpMessage,
|
||||||
|
Version: constants.FullVersion(),
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"goauthentik.io/internal/common"
|
"goauthentik.io/internal/common"
|
||||||
|
"goauthentik.io/internal/constants"
|
||||||
"goauthentik.io/internal/debug"
|
"goauthentik.io/internal/debug"
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||||
@ -23,7 +24,8 @@ Required environment variables:
|
|||||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Long: helpMessage,
|
Long: helpMessage,
|
||||||
|
Version: constants.FullVersion(),
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"goauthentik.io/internal/common"
|
"goauthentik.io/internal/common"
|
||||||
|
"goauthentik.io/internal/constants"
|
||||||
"goauthentik.io/internal/debug"
|
"goauthentik.io/internal/debug"
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||||
@ -23,7 +24,8 @@ Required environment variables:
|
|||||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Long: helpMessage,
|
Long: helpMessage,
|
||||||
|
Version: constants.FullVersion(),
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
|
@ -31,7 +31,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- redis:/data
|
- redis:/data
|
||||||
server:
|
server:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.0}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
@ -54,7 +54,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
worker:
|
worker:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.0}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
environment:
|
environment:
|
||||||
|
24
go.mod
24
go.mod
@ -1,8 +1,8 @@
|
|||||||
module goauthentik.io
|
module goauthentik.io
|
||||||
|
|
||||||
go 1.23
|
go 1.23.0
|
||||||
|
|
||||||
toolchain go1.23.0
|
toolchain go1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
beryju.io/ldap v0.1.0
|
beryju.io/ldap v0.1.0
|
||||||
@ -22,16 +22,16 @@ require (
|
|||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
||||||
github.com/pires/go-proxyproto v0.8.0
|
github.com/pires/go-proxyproto v0.8.0
|
||||||
github.com/prometheus/client_golang v1.20.5
|
github.com/prometheus/client_golang v1.21.0
|
||||||
github.com/redis/go-redis/v9 v9.7.0
|
github.com/redis/go-redis/v9 v9.7.1
|
||||||
github.com/sethvargo/go-envconfig v1.1.1
|
github.com/sethvargo/go-envconfig v1.1.1
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/wwt/guac v1.3.2
|
github.com/wwt/guac v1.3.2
|
||||||
goauthentik.io/api/v3 v3.2024123.6
|
goauthentik.io/api/v3 v3.2025020.1
|
||||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||||
golang.org/x/oauth2 v0.26.0
|
golang.org/x/oauth2 v0.27.0
|
||||||
golang.org/x/sync v0.11.0
|
golang.org/x/sync v0.11.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
||||||
@ -48,7 +48,7 @@ require (
|
|||||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||||
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 // indirect
|
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 // indirect
|
||||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect
|
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||||
github.com/go-logr/logr v1.4.1 // indirect
|
github.com/go-logr/logr v1.4.1 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||||
@ -62,23 +62,23 @@ require (
|
|||||||
github.com/go-openapi/validate v0.24.0 // indirect
|
github.com/go-openapi/validate v0.24.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/oklog/ulid v1.3.1 // indirect
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.55.0 // indirect
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.31.0 // indirect
|
golang.org/x/crypto v0.32.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.29.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.36.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
38
go.sum
38
go.sum
@ -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/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 h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno=
|
||||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
|
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
|
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||||
github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU=
|
github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU=
|
||||||
github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY=
|
github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
@ -207,8 +207,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
|
|||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
@ -239,17 +239,17 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
|
||||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||||
@ -299,8 +299,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
|
|||||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
goauthentik.io/api/v3 v3.2024123.6 h1:AGOCa7Fc/9eONCPEW4sEhTiyEBvxN57Lfqz1zm6Gy98=
|
goauthentik.io/api/v3 v3.2025020.1 h1:7922W4XiGif7lUCl2qlaeQJ3wSx1wDDDpXx8ryx0Hv0=
|
||||||
goauthentik.io/api/v3 v3.2024123.6/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
|
goauthentik.io/api/v3 v3.2025020.1/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-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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@ -312,8 +312,9 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
|||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -393,8 +394,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
|||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -447,8 +448,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@ -595,8 +597,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
|||||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION = "2024.12.3"
|
const VERSION = "2025.2.0"
|
||||||
|
8
lifecycle/aws/package-lock.json
generated
8
lifecycle/aws/package-lock.json
generated
@ -9,7 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aws-cdk": "^2.179.0",
|
"aws-cdk": "^2.1000.3",
|
||||||
"cross-env": "^7.0.3"
|
"cross-env": "^7.0.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -17,9 +17,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/aws-cdk": {
|
"node_modules/aws-cdk": {
|
||||||
"version": "2.179.0",
|
"version": "2.1000.3",
|
||||||
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.179.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1000.3.tgz",
|
||||||
"integrity": "sha512-aA2+8S2g4UBQHkUEt0mYd16VLt/ucR+QfyUJi34LDKRAhOCNDjPCZ4z9z/JEDyuni0BdzsYA55pnpDN9tMULpA==",
|
"integrity": "sha512-y0sU603gGWpVTwqDw9MKVHg3e1t49Mvve6t3YDOvjeKY195Vu6dgHlHjW4h8n1vX04r49NKfpoApG60V8sMbdw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aws-cdk": "^2.179.0",
|
"aws-cdk": "^2.1000.3",
|
||||||
"cross-env": "^7.0.3"
|
"cross-env": "^7.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ Parameters:
|
|||||||
Description: authentik Docker image
|
Description: authentik Docker image
|
||||||
AuthentikVersion:
|
AuthentikVersion:
|
||||||
Type: String
|
Type: String
|
||||||
Default: 2024.12.3
|
Default: 2025.2.0
|
||||||
Description: authentik Docker image tag
|
Description: authentik Docker image tag
|
||||||
AuthentikServerCPU:
|
AuthentikServerCPU:
|
||||||
Type: Number
|
Type: Number
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
|
"POT-Creation-Date: 2025-02-25 00:11+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -109,6 +109,10 @@ msgstr ""
|
|||||||
msgid "Extra description not available"
|
msgid "Extra description not available"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/core/api/groups.py
|
||||||
|
msgid "Cannot set group as parent of itself."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/core/api/providers.py
|
#: authentik/core/api/providers.py
|
||||||
msgid ""
|
msgid ""
|
||||||
"When not set all providers are returned. When set to true, only backchannel "
|
"When not set all providers are returned. When set to true, only backchannel "
|
||||||
@ -152,6 +156,14 @@ msgstr ""
|
|||||||
msgid "Remove user from group"
|
msgid "Remove user from group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/core/models.py
|
||||||
|
msgid "Enable superuser status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/core/models.py
|
||||||
|
msgid "Disable superuser status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/core/models.py
|
#: authentik/core/models.py
|
||||||
msgid "User's display name."
|
msgid "User's display name."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -500,57 +512,6 @@ msgstr ""
|
|||||||
msgid "Microsoft Entra Provider Mappings"
|
msgid "Microsoft Entra Provider Mappings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
#: authentik/stages/user_login/models.py
|
|
||||||
msgid ""
|
|
||||||
"Determines how long a session lasts. Default of 0 means that the sessions "
|
|
||||||
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "When set to true, connection tokens will be deleted upon disconnect."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Provider"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Providers"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Endpoint"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Endpoints"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Provider Property Mapping"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Provider Property Mappings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Connection token"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/models.py
|
|
||||||
msgid "RAC Connection tokens"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/views.py
|
|
||||||
msgid "Maximum connection limit reached."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/rac/views.py
|
|
||||||
msgid "(You are already connected in another tab/window)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/enterprise/providers/ssf/models.py
|
#: authentik/enterprise/providers/ssf/models.py
|
||||||
#: authentik/providers/oauth2/models.py
|
#: authentik/providers/oauth2/models.py
|
||||||
msgid "Signing Key"
|
msgid "Signing Key"
|
||||||
@ -651,7 +612,7 @@ msgstr ""
|
|||||||
msgid "Slack Webhook (Slack/Discord)"
|
msgid "Slack Webhook (Slack/Discord)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/events/models.py
|
#: authentik/events/models.py authentik/stages/authenticator_validate/models.py
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1105,6 +1066,14 @@ msgstr ""
|
|||||||
msgid "Client IP is not in an allowed country."
|
msgid "Client IP is not in an allowed country."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/policies/geoip/models.py
|
||||||
|
msgid "Distance from previous authentication is larger than threshold."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/policies/geoip/models.py
|
||||||
|
msgid "Distance is further than possible."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/policies/geoip/models.py
|
#: authentik/policies/geoip/models.py
|
||||||
msgid "GeoIP Policy"
|
msgid "GeoIP Policy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -1643,6 +1612,56 @@ msgstr ""
|
|||||||
msgid "Proxy Providers"
|
msgid "Proxy Providers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py authentik/stages/user_login/models.py
|
||||||
|
msgid ""
|
||||||
|
"Determines how long a session lasts. Default of 0 means that the sessions "
|
||||||
|
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "When set to true, connection tokens will be deleted upon disconnect."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Provider"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Providers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Endpoint"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Endpoints"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Provider Property Mapping"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Provider Property Mappings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Connection token"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/models.py
|
||||||
|
msgid "RAC Connection tokens"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/views.py
|
||||||
|
msgid "Maximum connection limit reached."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/providers/rac/views.py
|
||||||
|
msgid "(You are already connected in another tab/window)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/providers/radius/models.py
|
#: authentik/providers/radius/models.py
|
||||||
msgid "Shared secret between clients and server to hash packets."
|
msgid "Shared secret between clients and server to hash packets."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -2486,6 +2505,98 @@ msgstr ""
|
|||||||
msgid "Duo Devices"
|
msgid "Duo Devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Email OTP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
#: authentik/stages/email/models.py
|
||||||
|
msgid ""
|
||||||
|
"When enabled, global Email connection settings will be used and connection "
|
||||||
|
"settings below will be ignored."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Time the token sent is valid (Format: hours=3,minutes=17,seconds=300)."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Email Authenticator Setup Stage"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Email Authenticator Setup Stages"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
#: authentik/stages/authenticator_email/stage.py
|
||||||
|
#: authentik/stages/email/stage.py
|
||||||
|
msgid "Exception occurred while rendering E-mail template"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Email Device"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/models.py
|
||||||
|
msgid "Email Devices"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/stage.py
|
||||||
|
#: authentik/stages/authenticator_sms/stage.py
|
||||||
|
#: authentik/stages/authenticator_totp/stage.py
|
||||||
|
msgid "Code does not match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/stage.py
|
||||||
|
msgid "Invalid email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||||
|
#: authentik/stages/email/templates/email/password_reset.html
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" Hi %(username)s,\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" Email MFA code.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" If you did not request this code, please ignore this email. The code "
|
||||||
|
"above is valid for %(expires)s.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||||
|
#: authentik/stages/email/templates/email/password_reset.txt
|
||||||
|
#, python-format
|
||||||
|
msgid "Hi %(username)s,"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"Email MFA code\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"If you did not request this code, please ignore this email. The code above "
|
||||||
|
"is valid for %(expires)s.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/authenticator_sms/models.py
|
#: authentik/stages/authenticator_sms/models.py
|
||||||
msgid ""
|
msgid ""
|
||||||
"When enabled, the Phone number is only used during enrollment to verify the "
|
"When enabled, the Phone number is only used during enrollment to verify the "
|
||||||
@ -2518,11 +2629,6 @@ msgstr ""
|
|||||||
msgid "SMS Devices"
|
msgid "SMS Devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/authenticator_sms/stage.py
|
|
||||||
#: authentik/stages/authenticator_totp/stage.py
|
|
||||||
msgid "Code does not match"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/stages/authenticator_sms/stage.py
|
#: authentik/stages/authenticator_sms/stage.py
|
||||||
msgid "Invalid phone number"
|
msgid "Invalid phone number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -2745,12 +2851,6 @@ msgstr ""
|
|||||||
msgid "Account Confirmation"
|
msgid "Account Confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/email/models.py
|
|
||||||
msgid ""
|
|
||||||
"When enabled, global Email connection settings will be used and connection "
|
|
||||||
"settings below will be ignored."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/stages/email/models.py
|
#: authentik/stages/email/models.py
|
||||||
msgid "Activate users upon completion of stage."
|
msgid "Activate users upon completion of stage."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -2767,10 +2867,6 @@ msgstr ""
|
|||||||
msgid "Email Stages"
|
msgid "Email Stages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/email/stage.py
|
|
||||||
msgid "Exception occurred while rendering E-mail template"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/stages/email/stage.py
|
#: authentik/stages/email/stage.py
|
||||||
msgid "Successfully verified Email."
|
msgid "Successfully verified Email."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -2845,14 +2941,6 @@ msgid ""
|
|||||||
"This email was sent from the notification transport %(name)s.\n"
|
"This email was sent from the notification transport %(name)s.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/email/templates/email/password_reset.html
|
|
||||||
#, python-format
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
" Hi %(username)s,\n"
|
|
||||||
" "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/stages/email/templates/email/password_reset.html
|
#: authentik/stages/email/templates/email/password_reset.html
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
@ -2870,11 +2958,6 @@ msgid ""
|
|||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentik/stages/email/templates/email/password_reset.txt
|
|
||||||
#, python-format
|
|
||||||
msgid "Hi %(username)s,"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentik/stages/email/templates/email/password_reset.txt
|
#: authentik/stages/email/templates/email/password_reset.txt
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/authentik",
|
"name": "@goauthentik/authentik",
|
||||||
"version": "2024.12.3",
|
"version": "2025.2.0",
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
264
poetry.lock
generated
264
poetry.lock
generated
@ -392,13 +392,13 @@ typeguard = ">=2.13.3,<4.3.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aws-cdk-lib"
|
name = "aws-cdk-lib"
|
||||||
version = "2.179.0"
|
version = "2.180.0"
|
||||||
description = "Version 2 of the AWS Cloud Development Kit library"
|
description = "Version 2 of the AWS Cloud Development Kit library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "~=3.8"
|
python-versions = "~=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "aws_cdk_lib-2.179.0-py3-none-any.whl", hash = "sha256:1d7b88ee69067b8d58dac9eeb6697bbaf5d5c032a3070898389c41e7c4f3e3d7"},
|
{file = "aws_cdk_lib-2.180.0-py3-none-any.whl", hash = "sha256:5700a84dc4c2c6d323e596119fb4100e66aef6265a4d984bbe2e9341174d048b"},
|
||||||
{file = "aws_cdk_lib-2.179.0.tar.gz", hash = "sha256:b653a55754f4020a4b36e4ae183d213e76e27b18b842cbf9e430e9eccb700550"},
|
{file = "aws_cdk_lib-2.180.0.tar.gz", hash = "sha256:28ba2c75bd55886eb5e686c58be656c9ab29b895f774f9129eaa3255ffcd6b42"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -1694,18 +1694,17 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "duo-client"
|
name = "duo-client"
|
||||||
version = "5.3.0"
|
version = "5.4.0"
|
||||||
description = "Reference client for Duo Security APIs"
|
description = "Reference client for Duo Security APIs"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "duo_client-5.3.0-py3-none-any.whl", hash = "sha256:85614bb684cef96285268aef0c1e858df939f6e8a190fb2c707d700bb0215766"},
|
{file = "duo_client-5.4.0-py3-none-any.whl", hash = "sha256:092d2f79ca2dd7107f944807a109c98c08b99c2dd7fc422b979a248787852068"},
|
||||||
{file = "duo_client-5.3.0.tar.gz", hash = "sha256:afa5ef98a42f06965a2702ca41dba9c85c483abd945e0a440f0ec4871b7593bf"},
|
{file = "duo_client-5.4.0.tar.gz", hash = "sha256:8e0fec41006951ce7d0ac5281ddfef59f154e194c71d5a00d717e1769e9077bb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
setuptools = "*"
|
setuptools = "*"
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "durationpy"
|
name = "durationpy"
|
||||||
@ -2524,13 +2523,13 @@ zookeeper = ["kazoo (>=2.8.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kubernetes"
|
name = "kubernetes"
|
||||||
version = "32.0.0"
|
version = "32.0.1"
|
||||||
description = "Kubernetes python client"
|
description = "Kubernetes python client"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
files = [
|
files = [
|
||||||
{file = "kubernetes-32.0.0-py2.py3-none-any.whl", hash = "sha256:60fd8c29e8e43d9c553ca4811895a687426717deba9c0a66fb2dcc3f5ef96692"},
|
{file = "kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998"},
|
||||||
{file = "kubernetes-32.0.0.tar.gz", hash = "sha256:319fa840345a482001ac5d6062222daeb66ec4d1bcb3087402aed685adf0aecb"},
|
{file = "kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -3718,36 +3717,36 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg"
|
name = "psycopg"
|
||||||
version = "3.2.4"
|
version = "3.2.5"
|
||||||
description = "PostgreSQL database adapter for Python"
|
description = "PostgreSQL database adapter for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "psycopg-3.2.4-py3-none-any.whl", hash = "sha256:43665368ccd48180744cab26b74332f46b63b7e06e8ce0775547a3533883d381"},
|
{file = "psycopg-3.2.5-py3-none-any.whl", hash = "sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879"},
|
||||||
{file = "psycopg-3.2.4.tar.gz", hash = "sha256:f26f1346d6bf1ef5f5ef1714dd405c67fb365cfd1c6cea07de1792747b167b92"},
|
{file = "psycopg-3.2.5.tar.gz", hash = "sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
psycopg-c = {version = "3.2.4", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
|
psycopg-c = {version = "3.2.5", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
|
||||||
typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""}
|
typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""}
|
||||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
binary = ["psycopg-binary (==3.2.4)"]
|
binary = ["psycopg-binary (==3.2.5)"]
|
||||||
c = ["psycopg-c (==3.2.4)"]
|
c = ["psycopg-c (==3.2.5)"]
|
||||||
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
|
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "isort-psycopg", "isort[colors] (>=6.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
|
||||||
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
|
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||||
pool = ["psycopg-pool"]
|
pool = ["psycopg-pool"]
|
||||||
test = ["anyio (>=4.0)", "mypy (>=1.14)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
|
test = ["anyio (>=4.0)", "mypy (>=1.14)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg-c"
|
name = "psycopg-c"
|
||||||
version = "3.2.4"
|
version = "3.2.5"
|
||||||
description = "PostgreSQL database adapter for Python -- C optimisation distribution"
|
description = "PostgreSQL database adapter for Python -- C optimisation distribution"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "psycopg_c-3.2.4.tar.gz", hash = "sha256:22097a04263efb2efd2cc8b00a51fa90e23f9cd4a2e09903fe4d9c6923dac17a"},
|
{file = "psycopg_c-3.2.5.tar.gz", hash = "sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4548,29 +4547,29 @@ pyasn1 = ">=0.1.3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.9.6"
|
version = "0.9.7"
|
||||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"},
|
{file = "ruff-0.9.7-py3-none-linux_armv6l.whl", hash = "sha256:99d50def47305fe6f233eb8dabfd60047578ca87c9dcb235c9723ab1175180f4"},
|
||||||
{file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"},
|
{file = "ruff-0.9.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d59105ae9c44152c3d40a9c40d6331a7acd1cdf5ef404fbe31178a77b174ea66"},
|
||||||
{file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"},
|
{file = "ruff-0.9.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f313b5800483770bd540cddac7c90fc46f895f427b7820f18fe1822697f1fec9"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042ae32b41343888f59c0a4148f103208bf6b21c90118d51dc93a68366f4e903"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87862589373b33cc484b10831004e5e5ec47dc10d2b41ba770e837d4f429d721"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a17e1e01bee0926d351a1ee9bc15c445beae888f90069a6192a07a84af544b6b"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7c1f880ac5b2cbebd58b8ebde57069a374865c73f3bf41f05fe7a179c1c8ef22"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e63fc20143c291cab2841dbb8260e96bafbe1ba13fd3d60d28be2c71e312da49"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91ff963baed3e9a6a4eba2a02f4ca8eaa6eba1cc0521aec0987da8d62f53cbef"},
|
||||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"},
|
{file = "ruff-0.9.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88362e3227c82f63eaebf0b2eff5b88990280fb1ecf7105523883ba8c3aaf6fb"},
|
||||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"},
|
{file = "ruff-0.9.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0372c5a90349f00212270421fe91874b866fd3626eb3b397ede06cd385f6f7e0"},
|
||||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"},
|
{file = "ruff-0.9.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d76b8ab60e99e6424cd9d3d923274a1324aefce04f8ea537136b8398bbae0a62"},
|
||||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"},
|
{file = "ruff-0.9.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0c439bdfc8983e1336577f00e09a4e7a78944fe01e4ea7fe616d00c3ec69a3d0"},
|
||||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"},
|
{file = "ruff-0.9.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:115d1f15e8fdd445a7b4dc9a30abae22de3f6bcabeb503964904471691ef7606"},
|
||||||
{file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"},
|
{file = "ruff-0.9.7-py3-none-win32.whl", hash = "sha256:e9ece95b7de5923cbf38893f066ed2872be2f2f477ba94f826c8defdd6ec6b7d"},
|
||||||
{file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"},
|
{file = "ruff-0.9.7-py3-none-win_amd64.whl", hash = "sha256:3770fe52b9d691a15f0b87ada29c45324b2ace8f01200fb0c14845e499eb0c2c"},
|
||||||
{file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"},
|
{file = "ruff-0.9.7-py3-none-win_arm64.whl", hash = "sha256:b075a700b2533feb7a01130ff656a4ec0d5f340bb540ad98759b8401c32c2037"},
|
||||||
{file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"},
|
{file = "ruff-0.9.7.tar.gz", hash = "sha256:643757633417907510157b206e490c3aa11cab0c087c912f60e07fbafa87a4c6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4609,13 +4608,13 @@ django-query = ["django (>=3.2)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selenium"
|
name = "selenium"
|
||||||
version = "4.28.1"
|
version = "4.29.0"
|
||||||
description = "Official Python bindings for Selenium WebDriver"
|
description = "Official Python bindings for Selenium WebDriver"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "selenium-4.28.1-py3-none-any.whl", hash = "sha256:4238847e45e24e4472cfcf3554427512c7aab9443396435b1623ef406fff1cc1"},
|
{file = "selenium-4.29.0-py3-none-any.whl", hash = "sha256:ce5d26f1ddc1111641113653af33694c13947dd36c2df09cdd33f554351d372e"},
|
||||||
{file = "selenium-4.28.1.tar.gz", hash = "sha256:0072d08670d7ec32db901bd0107695a330cecac9f196e3afb3fa8163026e022a"},
|
{file = "selenium-4.29.0.tar.gz", hash = "sha256:3a62f7ec33e669364a6c0562a701deb69745b569c50d55f1a912bf8eb33358ba"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -4708,96 +4707,96 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setproctitle"
|
name = "setproctitle"
|
||||||
version = "1.3.4"
|
version = "1.3.5"
|
||||||
description = "A Python module to customize the process title"
|
description = "A Python module to customize the process title"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0f6661a69c68349172ba7b4d5dd65fec2b0917abc99002425ad78c3e58cf7595"},
|
{file = "setproctitle-1.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02870e0cb0de7f68a7a8a5b23c2bc0ce63821cab3d9b126f9be80bb6cd674c80"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:754bac5e470adac7f7ec2239c485cd0b75f8197ca8a5b86ffb20eb3a3676cc42"},
|
{file = "setproctitle-1.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55b278135be742b8901067479626d909f6613bd2d2c4fd0de6bb46f80e07a919"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7bc7088c15150745baf66db62a4ced4507d44419eb66207b609f91b64a682af"},
|
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53fc971f7bf7a674f571a23cdec70f2f0ac88152c59c06aa0808d0be6d834046"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a46ef3ecf61e4840fbc1145fdd38acf158d0da7543eda7b773ed2b30f75c2830"},
|
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb0500e1bc6f00b8ba696c3743ddff14c8679e3c2ca9d292c008ac51488d17cf"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcb09d5c0ffa043254ec9a734a73f3791fec8bf6333592f906bb2e91ed2af1a"},
|
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:995b3ac1b5fe510f4e1d1c19ebf19f4bceb448f2d6e8d99ea23f33cb6f1a277e"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06c16b7a91cdc5d700271899e4383384a61aae83a3d53d0e2e5a266376083342"},
|
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5a05e2c3fdfbda32b9c9da72d0506398d1efb5bd2c5981b9e12d3622eb3d4f9"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f9732e59863eaeedd3feef94b2b216cb86d40dda4fad2d0f0aaec3b31592716"},
|
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:310c7f4ca4c8476a9840b2cd4b22ee602a49a3c902fdcd2dd8284685abd10a9a"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e152f4ab9ea1632b5fecdd87cee354f2b2eb6e2dfc3aceb0eb36a01c1e12f94c"},
|
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:867af4a5c3d85484fbcc50ea88bcd375acf709cff88a3259575361849c0da351"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:020ea47a79b2bbd7bd7b94b85ca956ba7cb026e82f41b20d2e1dac4008cead25"},
|
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ec0a7fe9f1ba90900144489bc93ce7dd4dec3f3df1e7f188c9e58364fe4a4c5"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8c52b12b10e4057fc302bd09cb3e3f28bb382c30c044eb3396e805179a8260e4"},
|
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:aaee7acba2733a14a886488b7495bfec4a8d6407124c04a0946dbde1684230a3"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-win32.whl", hash = "sha256:a65a147f545f3fac86f11acb2d0b316d3e78139a9372317b7eb50561b2817ba0"},
|
{file = "setproctitle-1.3.5-cp310-cp310-win32.whl", hash = "sha256:bd2cccd972e4282af4ce2c13cd9ebdf07be157eabafd8ce648fffdc8ae6fbe28"},
|
||||||
{file = "setproctitle-1.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:66821fada6426998762a3650a37fba77e814a249a95b1183011070744aff47f6"},
|
{file = "setproctitle-1.3.5-cp310-cp310-win_amd64.whl", hash = "sha256:81f2328ac34c9584e1e5f87eea916c0bc48476a06606a07debae07acdd7ab5ea"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0f749f07002c2d6fecf37cedc43207a88e6c651926a470a5f229070cf791879"},
|
{file = "setproctitle-1.3.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1c8dcc250872385f2780a5ea58050b58cbc8b6a7e8444952a5a65c359886c593"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90ea8d302a5d30b948451d146e94674a3c5b020cc0ced9a1c28f8ddb0f203a5d"},
|
{file = "setproctitle-1.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ca82fae9eb4800231dd20229f06e8919787135a5581da245b8b05e864f34cc8b"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f859c88193ed466bee4eb9d45fbc29d2253e6aa3ccd9119c9a1d8d95f409a60d"},
|
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0424e1d33232322541cb36fb279ea5242203cd6f20de7b4fb2a11973d8e8c2ce"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3afa5a0ed08a477ded239c05db14c19af585975194a00adf594d48533b23701"},
|
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fec8340ab543144d04a9d805d80a0aad73fdeb54bea6ff94e70d39a676ea4ec0"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a78fce9018cc3e9a772b6537bbe3fe92380acf656c9f86db2f45e685af376e"},
|
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eab441c89f181271ab749077dcc94045a423e51f2fb0b120a1463ef9820a08d0"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d758e2eed2643afac5f2881542fbb5aa97640b54be20d0a5ed0691d02f0867d"},
|
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c371550a2288901a0dcd84192691ebd3197a43c95f3e0b396ed6d1cedf5c6c"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ef133a1a2ee378d549048a12d56f4ef0e2b9113b0b25b6b77821e9af94d50634"},
|
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:78288ff5f9c415c56595b2257ad218936dd9fa726b36341b373b31ca958590fe"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1d2a154b79d5fb42d1eff06e05e22f0e8091261d877dd47b37d31352b74ecc37"},
|
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f1f13a25fc46731acab518602bb1149bfd8b5fabedf8290a7c0926d61414769d"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:202eae632815571297833876a0f407d0d9c7ad9d843b38adbe687fe68c5192ee"},
|
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1534d6cd3854d035e40bf4c091984cbdd4d555d7579676d406c53c8f187c006f"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2b0080819859e80a7776ac47cf6accb4b7ad313baf55fabac89c000480dcd103"},
|
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62a01c76708daac78b9688ffb95268c57cb57fa90b543043cda01358912fe2db"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-win32.whl", hash = "sha256:9c9d7d1267dee8c6627963d9376efa068858cfc8f573c083b1b6a2d297a8710f"},
|
{file = "setproctitle-1.3.5-cp311-cp311-win32.whl", hash = "sha256:ea07f29735d839eaed985990a0ec42c8aecefe8050da89fec35533d146a7826d"},
|
||||||
{file = "setproctitle-1.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:475986ddf6df65d619acd52188336a20f616589403f5a5ceb3fc70cdc137037a"},
|
{file = "setproctitle-1.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:ab3ae11e10d13d514d4a5a15b4f619341142ba3e18da48c40e8614c5a1b5e3c3"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d06990dcfcd41bb3543c18dd25c8476fbfe1f236757f42fef560f6aa03ac8dfc"},
|
{file = "setproctitle-1.3.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:523424b9be4dea97d95b8a584b183f35c7bab2d0a3d995b01febf5b8a8de90e4"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:317218c9d8b17a010ab2d2f0851e8ef584077a38b1ba2b7c55c9e44e79a61e73"},
|
{file = "setproctitle-1.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b6ec1d86c1b4d7b5f2bdceadf213310cf24696b82480a2a702194b8a0bfbcb47"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb5fefb53b9d9f334a5d9ec518a36b92a10b936011ac8a6b6dffd60135f16459"},
|
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea6c505264275a43e9b2acd2acfc11ac33caf52bc3167c9fced4418a810f6b1c"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0855006261635e8669646c7c304b494b6df0a194d2626683520103153ad63cc9"},
|
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b91e68e6685998e6353f296100ecabc313a6cb3e413d66a03d74b988b61f5ff"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a88e466fcaee659679c1d64dcb2eddbcb4bfadffeb68ba834d9c173a25b6184"},
|
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc1fda208ae3a2285ad27aeab44c41daf2328abe58fa3270157a739866779199"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f963b6ed8ba33eda374a98d979e8a0eaf21f891b6e334701693a2c9510613c4c"},
|
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:828727d220e46f048b82289018300a64547b46aaed96bf8810c05fe105426b41"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:122c2e05697fa91f5d23f00bbe98a9da1bd457b32529192e934095fadb0853f1"},
|
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:83b016221cf80028b2947be20630faa14e3e72a403e35f0ba29550b4e856767b"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1bba0a866f5895d5b769d8c36b161271c7fd407e5065862ab80ff91c29fbe554"},
|
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6d8a411e752e794d052434139ca4234ffeceeb8d8d8ddc390a9051d7942b2726"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:97f1f861998e326e640708488c442519ad69046374b2c3fe9bcc9869b387f23c"},
|
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:50cfbf86b9c63a2c2903f1231f0a58edeb775e651ae1af84eec8430b0571f29b"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:726aee40357d4bdb70115442cb85ccc8e8bc554fc0bbbaa3a57cbe81df42287d"},
|
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f3b5e2eacd572444770026c9dd3ddc7543ce427cdf452d40a408d1e95beefb30"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-win32.whl", hash = "sha256:04d6ba8b816dbb0bfd62000b0c3e583160893e6e8c4233e1dca1a9ae4d95d924"},
|
{file = "setproctitle-1.3.5-cp312-cp312-win32.whl", hash = "sha256:cf4e3ded98027de2596c6cc5bbd3302adfb3ca315c848f56516bb0b7e88de1e9"},
|
||||||
{file = "setproctitle-1.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:9c76e43cb351ba8887371240b599925cdf3ecececc5dfb7125c71678e7722c55"},
|
{file = "setproctitle-1.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:f7a8c01ffd013dda2bed6e7d5cb59fbb609e72f805abf3ee98360f38f7758d9b"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d6e3b177e634aa6bbbfbf66d097b6d1cdb80fc60e912c7d8bace2e45699c07dd"},
|
{file = "setproctitle-1.3.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:162fd76781f57f42ddf27c475e5fef6a8df4fdd69b28dd554e53e2eb2bfe0f95"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6b17655a5f245b416e127e02087ea6347a48821cc4626bc0fd57101bfcd88afc"},
|
{file = "setproctitle-1.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4969d996bdfbe23bbd023cd0bae6c73a27371615c4ec5296a60cecce268659ef"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa5057a86df920faab8ee83960b724bace01a3231eb8e3f2c93d78283504d598"},
|
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd70c95a94473216e7c7a7a1f7d8ecbaca5b16d4ba93ddbfd32050fc485a8451"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149fdfb8a26a555780c4ce53c92e6d3c990ef7b30f90a675eca02e83c6d5f76d"},
|
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a887582bfdb6dcbc482db0ef9e630ad23ca95875806ef2b444bf6fbd7b7d7ca"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded03546938a987f463c68ab98d683af87a83db7ac8093bbc179e77680be5ba2"},
|
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:755671c39a9e70834eeec6dc6b61e344399c49881d2e7ea3534a1c69669dd9cc"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9f5b7f2bbc1754bc6292d9a7312071058e5a891b0391e6d13b226133f36aa"},
|
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ab52b4c2ce056a1b60d439991a81ca90f019488d4b4f64b2779e6badd3677e6"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0b19813c852566fa031902124336fa1f080c51e262fc90266a8c3d65ca47b74c"},
|
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36178b944019ec7fc52bb967ffeee296a11d373734a7be276755bedb3db5c141"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:db78b645dc63c0ccffca367a498f3b13492fb106a2243a1e998303ba79c996e2"},
|
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:269d41cd4f085b69821d1ee6599124f02dbbc79962b256e260b6c9021d037994"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b669aaac70bd9f03c070270b953f78d9ee56c4af6f0ff9f9cd3e6d1878c10b40"},
|
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d880630fd81d1b3bde121c352ca7ea2f2ff507ef40c3c011d0928ed491f912c9"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6dc3d656702791565994e64035a208be56b065675a5bc87b644c657d6d9e2232"},
|
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8a7fed67ab49f60bd51f3b4cffff3f8d754d1bb0a40e42869911301ec6519b65"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-win32.whl", hash = "sha256:091f682809a4d12291cf0205517619d2e7014986b7b00ebecfde3d76f8ae5a8f"},
|
{file = "setproctitle-1.3.5-cp313-cp313-win32.whl", hash = "sha256:e9c0d0cfcf715631b10d5950d04a9978f63bc46535724ef7c2eaf1dca9988642"},
|
||||||
{file = "setproctitle-1.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:adcd6ba863a315702184d92d3d3bbff290514f24a14695d310f02ae5e28bd1f7"},
|
{file = "setproctitle-1.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:e1d28eb98c91fbebd3e443a45c7da5d84974959851ef304c330eabd654a386f1"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:acf41cf91bbc5a36d1fa4455a818bb02bf2a4ccfed2f892ba166ba2fcbb0ec8a"},
|
{file = "setproctitle-1.3.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8995a1217b52d11d92bafd069961a47c5e13d8751ca976a32b3ecbbd471eaf9b"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ceb3ce3262b0e8e088e4117175591b7a82b3bdc5e52e33b1e74778b5fb53fd38"},
|
{file = "setproctitle-1.3.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae2ce64ea87837c4e3e65a7a232ff80cf09aa7d916e74cb34a245c47fcd87981"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2ef636a6a25fe7f3d5a064bea0116b74a4c8c7df9646b17dc7386c439a26cf"},
|
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b84de1780bbb0adc67560a113a0ea57e6ecfce2325680de8efe6c2a2f781ac"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28b8614de08679ae95bc4e8d6daaef6b61afdf027fa0d23bf13d619000286b3c"},
|
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b1d2628ac9868f960d7e87b3a9b2bb337104c3644b699e52e01efd7e106e4fe"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24f3c8be826a7d44181eac2269b15b748b76d98cd9a539d4c69f09321dcb5c12"},
|
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa912c4d08c66afda30dd5af8f2e9c59065dfc36a51edbd5419c3a7c962875aa"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc9d79b1bf833af63b7c720a6604eb16453ac1ad4e718eb8b59d1f97d986b98c"},
|
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4f783e100f8b451cd92fcabd3b831edfb1f7cb02be4a79b972f138e0001885"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fb693000b65842c85356b667d057ae0d0bac6519feca7e1c437cc2cfeb0afc59"},
|
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8ca56e39d10b6758046694a84950e5c5570a034c409ef3337595f64fc2cfa94d"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a166251b8fbc6f2755e2ce9d3c11e9edb0c0c7d2ed723658ff0161fbce26ac1c"},
|
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8915d69260ba6a6aaf9a48f6b53dbf9f8e4dc0cb4ae25bc5edb16a1666b6e47c"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:0361428e6378911a378841509c56ba472d991cbed1a7e3078ec0cacc103da44a"},
|
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7edd4fbb9fd17ed0e5a7f8bde9fa61c3987a34372084c45bab4eab6a2e554762"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:62d66e0423e3bd520b4c897063506b309843a8d07343fbfad04197e91a4edd28"},
|
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d0b19fd76d46b8096a463724739c3b09cf5ce38317f559f56f424f6ce7158de3"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-win32.whl", hash = "sha256:5edd01909348f3b0b2da329836d6b5419cd4869fec2e118e8ff3275b38af6267"},
|
{file = "setproctitle-1.3.5-cp38-cp38-win32.whl", hash = "sha256:53ce572cdbd43a0bed2aa24299cd823ebf233a7fa720cc7f8634728c213679c0"},
|
||||||
{file = "setproctitle-1.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:59e0dda9ad245921af0328035a961767026e1fa94bb65957ab0db0a0491325d6"},
|
{file = "setproctitle-1.3.5-cp38-cp38-win_amd64.whl", hash = "sha256:a58f00f35d6038ce1e8a9e5f87cb5ecce13ce118c5977a603566ad1fccc8d2cb"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bdaaa81a6e95a0a19fba0285f10577377f3503ae4e9988b403feba79da3e2f80"},
|
{file = "setproctitle-1.3.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c4b299b5bbadf00034978b8d741c85af25173146747eb9dab22596ec805a52d6"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ee5b19a2d794463bcc19153dfceede7beec784b4cf7967dec0bc0fc212ab3a3"},
|
{file = "setproctitle-1.3.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d57e7626329d4fb138da5ce15270b08a91326969956fb19c7a8fec2639066704"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3058a1bb0c767b3a6ccbb38b27ef870af819923eb732e21e44a3f300370fe159"},
|
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4272295721cf1fd2acf960b674d6dc09bec87f2a1e48995817b4ec4a3d483faf"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a97d37ee4fe0d1c6e87d2a97229c27a88787a8f4ebfbdeee95f91b818e52efe"},
|
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8305b6e6c203222c61318f338f1de08269ec66c247bf251593c215ff1fbeaf9"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e61dd7d05da11fc69bb86d51f1e0ee08f74dccf3ecf884c94de41135ffdc75d"},
|
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:becc9f3f605936506d2bd63d9cf817b7ee66b10d204184c4a633064dbed579d6"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb115d53dc2a1299ae72f1119c96a556db36073bacb6da40c47ece5db0d9587"},
|
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4629de80c47155a26e8d87a0a92d9428aa8d79ccfe2c20fd18888580619704e1"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:342570716e2647a51ea859b8a9126da9dc1a96a0153c9c0a3514effd60ab57ad"},
|
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f1af1d310b5b6cda692da52bd862a9833086c0a3f8380fa92505dd23857dcf60"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0ad212ae2b03951367a69584af034579b34e1e4199a75d377ef9f8e08ee299b1"},
|
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3bb6ea3d6e690677619508050bc681d86223723bdf67e4e8a8dffc3d04ca3044"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4afcb38e22122465013f4621b7e9ff8d42a7a48ae0ffeb94133a806cb91b4aad"},
|
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:322067ef1ffe70d297b00bee8a3862fed96021aa4318e3bce2d7c3bfa7a8d1e7"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:30bb223e6c3f95ad9e9bb2a113292759e947d1cfd60dbd4adb55851c370006b2"},
|
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1b58d49c32a46c48dcc2812635a89e6bee31139b03818da49a0bbaeaf01edef9"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-win32.whl", hash = "sha256:5f0521ed3bb9f02e9486573ea95e2062cd6bf036fa44e640bd54a06f22d85f35"},
|
{file = "setproctitle-1.3.5-cp39-cp39-win32.whl", hash = "sha256:707c23d4a88f5e66f1005d93558bf84eb45fc0fb0c4f33480a0c7d0895e8e848"},
|
||||||
{file = "setproctitle-1.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:0baadeb27f9e97e65922b4151f818b19c311d30b9efdb62af0e53b3db4006ce2"},
|
{file = "setproctitle-1.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:c64199a73d442a06d372b5286942229a43e86fa41bf36f317dcc60c036aff0bb"},
|
||||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:939d364a187b2adfbf6ae488664277e717d56c7951a4ddeb4f23b281bc50bfe5"},
|
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dc66b84beb0d5eb03abf0c3140c6d2cbe3d67ae9f0824a09dfa8c6ff164319a6"},
|
||||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb8a6a19be0cbf6da6fcbf3698b76c8af03fe83e4bd77c96c3922be3b88bf7da"},
|
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31dc9b330e7cac7685bdef790747c07914081c11ee1066eb0c597303dfb52010"},
|
||||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:779006f9e1aade9522a40e8d9635115ab15dd82b7af8e655967162e9c01e2573"},
|
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4028639b511f5e641d116b3b54ad70c637ebd1b4baac0948283daf11b104119f"},
|
||||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5519f2a7b8c535b0f1f77b30441476571373add72008230c81211ee17b423b57"},
|
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6bddef4e27d0ed74e44b58bf050bc3108591bf17d20d461fc59cd141282f849c"},
|
||||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:743836d484151334ebba1490d6907ca9e718fe815dcd5756f2a01bc3067d099c"},
|
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:9996be1d1df399c3cdc6d72ce0064e46bc74fc6e29fe16a328511a303dd4d418"},
|
||||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abda20aff8d1751e48d7967fa8945fef38536b82366c49be39b83678d4be3893"},
|
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cefc2dbdc48121022c3c05644cd3706f08e0b3c0ce07814d3c04daba0617936"},
|
||||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a2041b5788ce52f218b5be94af458e04470f997ab46fdebd57cf0b8374cc20e"},
|
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cef63879c79a570aabf7c158f453bf8d1285f0fda4b6b9b7a52d64b49c084d40"},
|
||||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2c3b1ce68746557aa6e6f4547e76883925cdc7f8d7c7a9f518acd203f1265ca5"},
|
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a863296a31fb578726c570314cb78ff3a3fddb65963dc01ea33731760f20a92c"},
|
||||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0b6a4cbabf024cb263a45bdef425760f14470247ff223f0ec51699ca9046c0fe"},
|
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b63bda3cb4b6526720dc7c6940b891c593f41771d119aeb8763875801ce2296d"},
|
||||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e55d7ecc68bdc80de5a553691a3ed260395d5362c19a266cf83cbb4e046551f"},
|
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95913af603da5b4c7635bf1fb67ecc5df7c18360b6cfb6740fd743bb150a6e17"},
|
||||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02ca3802902d91a89957f79da3ec44b25b5804c88026362cb85eea7c1fbdefd1"},
|
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36b130cf8fe76dc05ad1d48cc9ff3699eb1f0d8edbf6f46a3ce46a7041e49d7b"},
|
||||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:47669fc8ed8b27baa2d698104732234b5389f6a59c37c046f6bcbf9150f7a94e"},
|
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe3bfd5e51c24349d022e062a96c316a1b8862ea9a0cf5ea2a8b2ae008b77cec"},
|
||||||
{file = "setproctitle-1.3.4.tar.gz", hash = "sha256:3b40d32a3e1f04e94231ed6dfee0da9e43b4f9c6b5450d53e6dd7754c34e0c50"},
|
{file = "setproctitle-1.3.5.tar.gz", hash = "sha256:1e6eaeaf8a734d428a95d8c104643b39af7d247d604f40a7bebcf3960a853c5e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -5007,13 +5006,13 @@ wsproto = ">=0.14"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twilio"
|
name = "twilio"
|
||||||
version = "9.4.5"
|
version = "9.4.6"
|
||||||
description = "Twilio API client and TwiML generator"
|
description = "Twilio API client and TwiML generator"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7.0"
|
python-versions = ">=3.7.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "twilio-9.4.5-py2.py3-none-any.whl", hash = "sha256:284295946a5dcdaae65de9116c35db9065e1f3bd237d81da05b89fe1825013c6"},
|
{file = "twilio-9.4.6-py2.py3-none-any.whl", hash = "sha256:6d7d677fa9ded4ee0c366ad0155a1e0af51e129109af603b6ec9cdc8826a5c37"},
|
||||||
{file = "twilio-9.4.5.tar.gz", hash = "sha256:8db69103a850cd05aaaa6bfb6952ef7a5d784aaff83f01d9a0c594b5ce784cd1"},
|
{file = "twilio-9.4.6.tar.gz", hash = "sha256:ff33a6c3609f4a0769d02c4eb75f7ab55ff2ba962762b076cd39ef7da56fdaa4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -5854,12 +5853,13 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zxcvbn"
|
name = "zxcvbn"
|
||||||
version = "4.4.28"
|
version = "4.5.0"
|
||||||
description = ""
|
description = ""
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "zxcvbn-4.4.28.tar.gz", hash = "sha256:151bd816817e645e9064c354b13544f85137ea3320ca3be1fb6873ea75ef7dc1"},
|
{file = "zxcvbn-4.5.0-py2.py3-none-any.whl", hash = "sha256:2b6eed621612ce6d65e6e4c7455b966acee87d0280e257956b1f06ccc66bd5ff"},
|
||||||
|
{file = "zxcvbn-4.5.0.tar.gz", hash = "sha256:70392c0fff39459d7f55d0211151401e79e76fcc6e2c22b61add62900359c7c1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "authentik"
|
name = "authentik"
|
||||||
version = "2024.12.3"
|
version = "2025.2.0"
|
||||||
description = ""
|
description = ""
|
||||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||||
|
|
||||||
|
10
schema.yml
10
schema.yml
@ -1,7 +1,7 @@
|
|||||||
openapi: 3.0.3
|
openapi: 3.0.3
|
||||||
info:
|
info:
|
||||||
title: authentik
|
title: authentik
|
||||||
version: 2024.12.3
|
version: 2025.2.0
|
||||||
description: Making authentication simple.
|
description: Making authentication simple.
|
||||||
contact:
|
contact:
|
||||||
email: hello@goauthentik.io
|
email: hello@goauthentik.io
|
||||||
@ -39482,6 +39482,7 @@ components:
|
|||||||
- authentik.providers.ldap
|
- authentik.providers.ldap
|
||||||
- authentik.providers.oauth2
|
- authentik.providers.oauth2
|
||||||
- authentik.providers.proxy
|
- authentik.providers.proxy
|
||||||
|
- authentik.providers.rac
|
||||||
- authentik.providers.radius
|
- authentik.providers.radius
|
||||||
- authentik.providers.saml
|
- authentik.providers.saml
|
||||||
- authentik.providers.scim
|
- authentik.providers.scim
|
||||||
@ -39522,7 +39523,6 @@ components:
|
|||||||
- authentik.enterprise.audit
|
- authentik.enterprise.audit
|
||||||
- authentik.enterprise.providers.google_workspace
|
- authentik.enterprise.providers.google_workspace
|
||||||
- authentik.enterprise.providers.microsoft_entra
|
- authentik.enterprise.providers.microsoft_entra
|
||||||
- authentik.enterprise.providers.rac
|
|
||||||
- authentik.enterprise.providers.ssf
|
- authentik.enterprise.providers.ssf
|
||||||
- authentik.enterprise.stages.authenticator_endpoint_gdtc
|
- authentik.enterprise.stages.authenticator_endpoint_gdtc
|
||||||
- authentik.enterprise.stages.source
|
- authentik.enterprise.stages.source
|
||||||
@ -46625,6 +46625,9 @@ components:
|
|||||||
- authentik_providers_oauth2.scopemapping
|
- authentik_providers_oauth2.scopemapping
|
||||||
- authentik_providers_oauth2.oauth2provider
|
- authentik_providers_oauth2.oauth2provider
|
||||||
- authentik_providers_proxy.proxyprovider
|
- authentik_providers_proxy.proxyprovider
|
||||||
|
- authentik_providers_rac.racprovider
|
||||||
|
- authentik_providers_rac.endpoint
|
||||||
|
- authentik_providers_rac.racpropertymapping
|
||||||
- authentik_providers_radius.radiusprovider
|
- authentik_providers_radius.radiusprovider
|
||||||
- authentik_providers_radius.radiusproviderpropertymapping
|
- authentik_providers_radius.radiusproviderpropertymapping
|
||||||
- authentik_providers_saml.samlprovider
|
- authentik_providers_saml.samlprovider
|
||||||
@ -46694,9 +46697,6 @@ components:
|
|||||||
- authentik_providers_google_workspace.googleworkspaceprovidermapping
|
- authentik_providers_google_workspace.googleworkspaceprovidermapping
|
||||||
- authentik_providers_microsoft_entra.microsoftentraprovider
|
- authentik_providers_microsoft_entra.microsoftentraprovider
|
||||||
- authentik_providers_microsoft_entra.microsoftentraprovidermapping
|
- authentik_providers_microsoft_entra.microsoftentraprovidermapping
|
||||||
- authentik_providers_rac.racprovider
|
|
||||||
- authentik_providers_rac.endpoint
|
|
||||||
- authentik_providers_rac.racpropertymapping
|
|
||||||
- authentik_providers_ssf.ssfprovider
|
- authentik_providers_ssf.ssfprovider
|
||||||
- authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage
|
- authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage
|
||||||
- authentik_stages_source.sourcestage
|
- authentik_stages_source.sourcestage
|
||||||
|
@ -4,7 +4,7 @@ This package provides a generated API Client for [authentik](https://goauthentik
|
|||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
See https://docs.goauthentik.io/docs/developer-docs/making-schema-changes
|
See https://docs.goauthentik.io/docs/developer-docs/api/making-schema-changes#building-the-web-client
|
||||||
|
|
||||||
### Consuming
|
### Consuming
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ const interfaces = [
|
|||||||
["user/UserInterface.ts", "user"],
|
["user/UserInterface.ts", "user"],
|
||||||
["flow/FlowInterface.ts", "flow"],
|
["flow/FlowInterface.ts", "flow"],
|
||||||
["standalone/api-browser/index.ts", "standalone/api-browser"],
|
["standalone/api-browser/index.ts", "standalone/api-browser"],
|
||||||
["enterprise/rac/index.ts", "enterprise/rac"],
|
["rac/index.ts", "rac"],
|
||||||
["standalone/loading/index.ts", "standalone/loading"],
|
["standalone/loading/index.ts", "standalone/loading"],
|
||||||
["polyfill/poly.ts", "."],
|
["polyfill/poly.ts", "."],
|
||||||
];
|
];
|
||||||
@ -88,7 +88,11 @@ const baseArgs = {
|
|||||||
treeShaking: true,
|
treeShaking: true,
|
||||||
external: ["*.woff", "*.woff2"],
|
external: ["*.woff", "*.woff2"],
|
||||||
tsconfig: "./tsconfig.json",
|
tsconfig: "./tsconfig.json",
|
||||||
loader: { ".css": "text", ".md": "text" },
|
loader: {
|
||||||
|
".css": "text",
|
||||||
|
".md": "text",
|
||||||
|
".mdx": "text",
|
||||||
|
},
|
||||||
define: definitions,
|
define: definitions,
|
||||||
format: "esm",
|
format: "esm",
|
||||||
logOverride: {
|
logOverride: {
|
||||||
|
8
web/package-lock.json
generated
8
web/package-lock.json
generated
@ -23,7 +23,7 @@
|
|||||||
"@floating-ui/dom": "^1.6.11",
|
"@floating-ui/dom": "^1.6.11",
|
||||||
"@formatjs/intl-listformat": "^7.5.7",
|
"@formatjs/intl-listformat": "^7.5.7",
|
||||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||||
"@goauthentik/api": "^2024.12.3-1739814462",
|
"@goauthentik/api": "^2025.2.0-1740418530",
|
||||||
"@lit-labs/ssr": "^3.2.2",
|
"@lit-labs/ssr": "^3.2.2",
|
||||||
"@lit/context": "^1.1.2",
|
"@lit/context": "^1.1.2",
|
||||||
"@lit/localize": "^0.12.2",
|
"@lit/localize": "^0.12.2",
|
||||||
@ -1814,9 +1814,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@goauthentik/api": {
|
"node_modules/@goauthentik/api": {
|
||||||
"version": "2024.12.3-1739814462",
|
"version": "2025.2.0-1740418530",
|
||||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.12.3-1739814462.tgz",
|
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.2.0-1740418530.tgz",
|
||||||
"integrity": "sha512-qWGsq7zP0rG1PfjZA+iimaX4cVkd1n2JA/WceTOKgBmqnomQSI7SJNkdSpD+Qdy76PI0UuQWN73PInq/3rmm5Q=="
|
"integrity": "sha512-vFoIzmEuQ7sbWxIEFP7l7OwEMt8M9TqvxScyv0liQSgGd/xanc2W/R+JuOdhq9ePrCfXa1YcmuZtT41HZXFP6g=="
|
||||||
},
|
},
|
||||||
"node_modules/@goauthentik/web": {
|
"node_modules/@goauthentik/web": {
|
||||||
"resolved": "",
|
"resolved": "",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@floating-ui/dom": "^1.6.11",
|
"@floating-ui/dom": "^1.6.11",
|
||||||
"@formatjs/intl-listformat": "^7.5.7",
|
"@formatjs/intl-listformat": "^7.5.7",
|
||||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||||
"@goauthentik/api": "^2024.12.3-1739814462",
|
"@goauthentik/api": "^2025.2.0-1740418530",
|
||||||
"@lit-labs/ssr": "^3.2.2",
|
"@lit-labs/ssr": "^3.2.2",
|
||||||
"@lit/context": "^1.1.2",
|
"@lit/context": "^1.1.2",
|
||||||
"@lit/localize": "^0.12.2",
|
"@lit/localize": "^0.12.2",
|
||||||
|
@ -6,7 +6,7 @@ const config: KnipConfig = {
|
|||||||
"./src/user/UserInterface.ts",
|
"./src/user/UserInterface.ts",
|
||||||
"./src/flow/FlowInterface.ts",
|
"./src/flow/FlowInterface.ts",
|
||||||
"./src/standalone/api-browser/index.ts",
|
"./src/standalone/api-browser/index.ts",
|
||||||
"./src/enterprise/rac/index.ts",
|
"./src/rac/index.ts",
|
||||||
"./src/standalone/loading/index.ts",
|
"./src/standalone/loading/index.ts",
|
||||||
"./src/polyfill/poly.ts",
|
"./src/polyfill/poly.ts",
|
||||||
],
|
],
|
||||||
|
@ -7,6 +7,7 @@ import "@goauthentik/components/ak-radio-input";
|
|||||||
import "@goauthentik/components/ak-switch-input";
|
import "@goauthentik/components/ak-switch-input";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import "@goauthentik/components/ak-textarea-input";
|
import "@goauthentik/components/ak-textarea-input";
|
||||||
|
import "@goauthentik/elements/Alert.js";
|
||||||
import {
|
import {
|
||||||
CapabilitiesEnum,
|
CapabilitiesEnum,
|
||||||
WithCapabilitiesConfig,
|
WithCapabilitiesConfig,
|
||||||
@ -21,7 +22,7 @@ import "@goauthentik/elements/forms/SearchSelect";
|
|||||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { TemplateResult, html } from "lit";
|
import { TemplateResult, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
@ -120,7 +121,12 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderForm(): TemplateResult {
|
renderForm(): TemplateResult {
|
||||||
|
const alertMsg = msg(
|
||||||
|
"Using this form will only create an Application. In order to authenticate with the application, you will have to manually pair it with a Provider.",
|
||||||
|
);
|
||||||
|
|
||||||
return html`<form class="pf-c-form pf-m-horizontal">
|
return html`<form class="pf-c-form pf-m-horizontal">
|
||||||
|
${this.instance ? nothing : html`<ak-alert level="pf-m-info">${alertMsg}</ak-alert>`}
|
||||||
<ak-text-input
|
<ak-text-input
|
||||||
name="name"
|
name="name"
|
||||||
value=${ifDefined(this.instance?.name)}
|
value=${ifDefined(this.instance?.name)}
|
||||||
|
@ -50,7 +50,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
|||||||
}
|
}
|
||||||
pageDescription(): string {
|
pageDescription(): string {
|
||||||
return msg(
|
return msg(
|
||||||
str`External applications that use ${this.brand.brandingTitle || "authentik"} as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`,
|
str`External applications that use ${this.brand?.brandingTitle ?? "authentik"} as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pageIcon(): string {
|
pageIcon(): string {
|
||||||
@ -85,10 +85,6 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSectionBefore(): TemplateResult {
|
|
||||||
return html`<ak-application-wizard-hint></ak-application-wizard-hint>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSidebarAfter(): TemplateResult {
|
renderSidebarAfter(): TemplateResult {
|
||||||
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
||||||
<div class="pf-c-card">
|
<div class="pf-c-card">
|
||||||
@ -160,12 +156,21 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderObjectCreate(): TemplateResult {
|
renderObjectCreate(): TemplateResult {
|
||||||
return html`<ak-forms-modal .open=${getURLParam("createForm", false)}>
|
return html` <ak-application-wizard .open=${getURLParam("createWizard", false)}>
|
||||||
<span slot="submit"> ${msg("Create")} </span>
|
<button
|
||||||
<span slot="header"> ${msg("Create Application")} </span>
|
slot="trigger"
|
||||||
<ak-application-form slot="form"> </ak-application-form>
|
class="pf-c-button pf-m-primary"
|
||||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
data-ouia-component-id="start-application-wizard"
|
||||||
</ak-forms-modal>`;
|
>
|
||||||
|
${msg("Create with Provider")}
|
||||||
|
</button>
|
||||||
|
</ak-application-wizard>
|
||||||
|
<ak-forms-modal .open=${getURLParam("createForm", false)}>
|
||||||
|
<span slot="submit"> ${msg("Create")} </span>
|
||||||
|
<span slot="header"> ${msg("Create Application")} </span>
|
||||||
|
<ak-application-form slot="form"> </ak-application-form>
|
||||||
|
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||||
|
</ak-forms-modal>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export class ApplicationWizardStep extends WizardStep {
|
|||||||
// As recommended in [WizardStep](../../../components/ak-wizard/WizardStep.ts), we override
|
// As recommended in [WizardStep](../../../components/ak-wizard/WizardStep.ts), we override
|
||||||
// these fields and provide them to all the child classes.
|
// these fields and provide them to all the child classes.
|
||||||
wizardTitle = msg("New application");
|
wizardTitle = msg("New application");
|
||||||
wizardDescription = msg("Create a new application");
|
wizardDescription = msg("Create a new application and configure a provider for it.");
|
||||||
canCancel = true;
|
canCancel = true;
|
||||||
|
|
||||||
// This should be overridden in the children for more precise targeting.
|
// This should be overridden in the children for more precise targeting.
|
||||||
|
@ -31,9 +31,9 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
|||||||
|
|
||||||
@property({ type: Array })
|
@property({ type: Array })
|
||||||
allowedTypes: PolicyBindingCheckTarget[] = [
|
allowedTypes: PolicyBindingCheckTarget[] = [
|
||||||
|
PolicyBindingCheckTarget.policy,
|
||||||
PolicyBindingCheckTarget.group,
|
PolicyBindingCheckTarget.group,
|
||||||
PolicyBindingCheckTarget.user,
|
PolicyBindingCheckTarget.user,
|
||||||
PolicyBindingCheckTarget.policy,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@property({ type: Array })
|
@property({ type: Array })
|
||||||
|
@ -58,9 +58,9 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
|
|||||||
|
|
||||||
@property({ type: Array })
|
@property({ type: Array })
|
||||||
allowedTypes: PolicyBindingCheckTarget[] = [
|
allowedTypes: PolicyBindingCheckTarget[] = [
|
||||||
|
PolicyBindingCheckTarget.policy,
|
||||||
PolicyBindingCheckTarget.group,
|
PolicyBindingCheckTarget.group,
|
||||||
PolicyBindingCheckTarget.user,
|
PolicyBindingCheckTarget.user,
|
||||||
PolicyBindingCheckTarget.policy,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@property({ type: Array })
|
@property({ type: Array })
|
||||||
|
@ -105,6 +105,22 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
|
|||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${msg("Maximum distance")}
|
||||||
|
name="historyMaxDistanceKm"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
value="${first(this.instance?.historyMaxDistanceKm, 100)}"
|
||||||
|
class="pf-c-form-control"
|
||||||
|
/>
|
||||||
|
<p class="pf-c-form__helper-text">
|
||||||
|
${msg(
|
||||||
|
"Maximum distance a login attempt is allowed from in kilometers.",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal
|
||||||
label=${msg("Distance tolerance")}
|
label=${msg("Distance tolerance")}
|
||||||
name="distanceToleranceKm"
|
name="distanceToleranceKm"
|
||||||
@ -133,27 +149,6 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
|
|||||||
${msg("Amount of previous login events to check against.")}
|
${msg("Amount of previous login events to check against.")}
|
||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Maximum distance")}
|
|
||||||
name="historyMaxDistanceKm"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
min="1"
|
|
||||||
value="${first(this.instance?.historyMaxDistanceKm, 100)}"
|
|
||||||
class="pf-c-form-control"
|
|
||||||
/>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg(
|
|
||||||
"Maximum distance a login attempt is allowed from in kilometers.",
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
</div>
|
|
||||||
</ak-form-group>
|
|
||||||
<ak-form-group>
|
|
||||||
<span slot="header"> ${msg("Distance settings (Impossible travel)")} </span>
|
|
||||||
<div slot="body" class="pf-c-form">
|
|
||||||
<ak-form-element-horizontal name="checkImpossibleTravel">
|
<ak-form-element-horizontal name="checkImpossibleTravel">
|
||||||
<label class="pf-c-switch">
|
<label class="pf-c-switch">
|
||||||
<input
|
<input
|
||||||
|
@ -4,7 +4,7 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
|||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import renderDescriptionList from "@goauthentik/components/DescriptionList";
|
import renderDescriptionList from "@goauthentik/components/DescriptionList";
|
||||||
import "@goauthentik/components/events/ObjectChangelog";
|
import "@goauthentik/components/events/ObjectChangelog";
|
||||||
import MDProviderOAuth2 from "@goauthentik/docs/add-secure-apps/providers/oauth2/index.md";
|
import MDProviderOAuth2 from "@goauthentik/docs/add-secure-apps/providers/oauth2/index.mdx";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
|
@ -13,7 +13,7 @@ import MDNginxStandalone from "@goauthentik/docs/add-secure-apps/providers/proxy
|
|||||||
import MDTraefikCompose from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_compose.md";
|
import MDTraefikCompose from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_compose.md";
|
||||||
import MDTraefikIngress from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_ingress.md";
|
import MDTraefikIngress from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_ingress.md";
|
||||||
import MDTraefikStandalone from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_standalone.md";
|
import MDTraefikStandalone from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_standalone.md";
|
||||||
import MDHeaderAuthentication from "@goauthentik/docs/add-secure-apps/providers/proxy/header_authentication.md";
|
import MDHeaderAuthentication from "@goauthentik/docs/add-secure-apps/providers/proxy/header_authentication.mdx";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/Markdown";
|
import "@goauthentik/elements/Markdown";
|
||||||
@ -118,7 +118,7 @@ export class ProxyProviderViewPage extends AKElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderConfig(): TemplateResult {
|
renderConfig(): TemplateResult {
|
||||||
const serves = [
|
const servers = [
|
||||||
{
|
{
|
||||||
label: msg("Nginx (Ingress)"),
|
label: msg("Nginx (Ingress)"),
|
||||||
md: MDNginxIngress,
|
md: MDNginxIngress,
|
||||||
@ -184,7 +184,7 @@ export class ProxyProviderViewPage extends AKElement {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
return html`<ak-tabs pageIdentifier="proxy-setup">
|
return html`<ak-tabs pageIdentifier="proxy-setup">
|
||||||
${serves.map((server) => {
|
${servers.map((server) => {
|
||||||
return html`<section
|
return html`<section
|
||||||
slot="page-${convertToSlug(server.label)}"
|
slot="page-${convertToSlug(server.label)}"
|
||||||
data-tab-title="${server.label}"
|
data-tab-title="${server.label}"
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 772 KiB After Width: | Height: | Size: 628 KiB |
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
|||||||
export const ERROR_CLASS = "pf-m-danger";
|
export const ERROR_CLASS = "pf-m-danger";
|
||||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||||
export const CURRENT_CLASS = "pf-m-current";
|
export const CURRENT_CLASS = "pf-m-current";
|
||||||
export const VERSION = "2024.12.3";
|
export const VERSION = "2025.2.0";
|
||||||
export const TITLE_DEFAULT = "authentik";
|
export const TITLE_DEFAULT = "authentik";
|
||||||
export const ROUTE_SEPARATOR = ";";
|
export const ROUTE_SEPARATOR = ";";
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ export interface GlobalAuthentik {
|
|||||||
build: string;
|
build: string;
|
||||||
api: {
|
api: {
|
||||||
base: string;
|
base: string;
|
||||||
|
relBase: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export function globalAK(): GlobalAuthentik {
|
|||||||
ak.brand = CurrentBrandFromJSON(ak.brand);
|
ak.brand = CurrentBrandFromJSON(ak.brand);
|
||||||
ak.config = ConfigFromJSON(ak.config);
|
ak.config = ConfigFromJSON(ak.config);
|
||||||
}
|
}
|
||||||
|
const apiBase = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||||
if (!ak) {
|
if (!ak) {
|
||||||
return {
|
return {
|
||||||
config: ConfigFromJSON({
|
config: ConfigFromJSON({
|
||||||
@ -39,7 +41,8 @@ export function globalAK(): GlobalAuthentik {
|
|||||||
versionSubdomain: "",
|
versionSubdomain: "",
|
||||||
build: "",
|
build: "",
|
||||||
api: {
|
api: {
|
||||||
base: process.env.AK_API_BASE_PATH || window.location.origin,
|
base: apiBase.toString(),
|
||||||
|
relBase: apiBase.pathname,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ html > form > input {
|
|||||||
left: -2000px;
|
left: -2000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*#region Icons*/
|
||||||
|
|
||||||
.pf-icon {
|
.pf-icon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@ -54,6 +56,18 @@ html > form > input {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pf-c-form-control {
|
||||||
|
--pf-c-form-control--m-caps-lock--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg fill='%23aaabac' viewBox='0 0 56 56' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 20.7812 37.6211 L 35.2421 37.6211 C 38.5233 37.6211 40.2577 35.6992 40.2577 32.6055 L 40.2577 28.4570 L 49.1404 28.4570 C 51.0859 28.4570 52.6329 27.3086 52.6329 25.5039 C 52.6329 24.4024 52.0703 23.5351 51.0158 22.6211 L 30.9062 4.8789 C 29.9452 4.0351 29.0546 3.4727 27.9999 3.4727 C 26.9687 3.4727 26.0780 4.0351 25.1171 4.8789 L 4.9843 22.6445 C 3.8828 23.6055 3.3671 24.4024 3.3671 25.5039 C 3.3671 27.3086 4.9140 28.4570 6.8828 28.4570 L 15.7421 28.4570 L 15.7421 32.6055 C 15.7421 35.6992 17.4999 37.6211 20.7812 37.6211 Z M 21.1562 34.0820 C 20.2655 34.0820 19.6562 33.4961 19.6562 32.6055 L 19.6562 25.7149 C 19.6562 25.1524 19.4452 24.9180 18.8828 24.9180 L 8.6640 24.9180 C 8.4999 24.9180 8.4296 24.8476 8.4296 24.7305 C 8.4296 24.6367 8.4530 24.5430 8.5702 24.4492 L 27.5077 7.9961 C 27.7187 7.8086 27.8359 7.7383 27.9999 7.7383 C 28.1640 7.7383 28.3046 7.8086 28.4921 7.9961 L 47.4532 24.4492 C 47.5703 24.5430 47.5939 24.6367 47.5939 24.7305 C 47.5939 24.8476 47.4998 24.9180 47.3356 24.9180 L 37.1406 24.9180 C 36.5780 24.9180 36.3671 25.1524 36.3671 25.7149 L 36.3671 32.6055 C 36.3671 33.4727 35.7109 34.0820 34.8671 34.0820 Z M 19.7733 52.5273 L 36.0624 52.5273 C 38.7577 52.5273 40.3046 51.0273 40.3046 48.3086 L 40.3046 44.9336 C 40.3046 42.2148 38.7577 40.6680 36.0624 40.6680 L 19.7733 40.6680 C 17.0546 40.6680 15.5077 42.2383 15.5077 44.9336 L 15.5077 48.3086 C 15.5077 51.0039 17.0546 52.5273 19.7733 52.5273 Z M 20.3124 49.2227 C 19.4921 49.2227 19.0468 48.8008 19.0468 47.9805 L 19.0468 45.2617 C 19.0468 44.4414 19.4921 43.9727 20.3124 43.9727 L 35.5233 43.9727 C 36.3202 43.9727 36.7655 44.4414 36.7655 45.2617 L 36.7655 47.9805 C 36.7655 48.8008 36.3202 49.2227 35.5233 49.2227 Z'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-c-form-control.pf-m-icon.pf-m-caps-lock {
|
||||||
|
--pf-c-form-control--m-icon--BackgroundUrl: var(
|
||||||
|
--pf-c-form-control--m-caps-lock--BackgroundUrl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#endregion*/
|
||||||
|
|
||||||
.pf-c-page__header {
|
.pf-c-page__header {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
background-color: var(--ak-dark-background-light);
|
background-color: var(--ak-dark-background-light);
|
||||||
|
@ -3,6 +3,7 @@ import type { AbstractConstructor } from "@goauthentik/elements/types.js";
|
|||||||
|
|
||||||
import { consume } from "@lit/context";
|
import { consume } from "@lit/context";
|
||||||
import type { LitElement } from "lit";
|
import type { LitElement } from "lit";
|
||||||
|
import { state } from "lit/decorators.js";
|
||||||
|
|
||||||
import type { CurrentBrand } from "@goauthentik/api";
|
import type { CurrentBrand } from "@goauthentik/api";
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ export function WithBrandConfig<T extends AbstractConstructor<LitElement>>(
|
|||||||
) {
|
) {
|
||||||
abstract class WithBrandProvider extends superclass {
|
abstract class WithBrandProvider extends superclass {
|
||||||
@consume({ context: authentikBrandContext, subscribe })
|
@consume({ context: authentikBrandContext, subscribe })
|
||||||
|
@state()
|
||||||
public brand!: CurrentBrand;
|
public brand!: CurrentBrand;
|
||||||
}
|
}
|
||||||
return WithBrandProvider;
|
return WithBrandProvider;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { AkControlElement } from "@goauthentik/elements/AkControlElement.js";
|
import { AkControlElement } from "@goauthentik/elements/AkControlElement.js";
|
||||||
import { debounce } from "@goauthentik/elements/utils/debounce";
|
import { debounce } from "@goauthentik/elements/utils/debounce";
|
||||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { PropertyValues, html } from "lit";
|
import { PropertyValues, html } from "lit";
|
||||||
@ -12,6 +11,11 @@ import type { Pagination } from "@goauthentik/api";
|
|||||||
|
|
||||||
import "./ak-dual-select";
|
import "./ak-dual-select";
|
||||||
import { AkDualSelect } from "./ak-dual-select";
|
import { AkDualSelect } from "./ak-dual-select";
|
||||||
|
import {
|
||||||
|
DualSelectChangeEvent,
|
||||||
|
DualSelectPaginatorNavEvent,
|
||||||
|
DualSelectSearchEvent,
|
||||||
|
} from "./events";
|
||||||
import type { DataProvider, DualSelectPair } from "./types";
|
import type { DataProvider, DualSelectPair } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +30,7 @@ import type { DataProvider, DualSelectPair } from "./types";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@customElement("ak-dual-select-provider")
|
@customElement("ak-dual-select-provider")
|
||||||
export class AkDualSelectProvider extends CustomListenerElement(AkControlElement) {
|
export class AkDualSelectProvider extends AkControlElement {
|
||||||
/** A function that takes a page and returns the DualSelectPair[] collection with which to update
|
/** A function that takes a page and returns the DualSelectPair[] collection with which to update
|
||||||
* the "Available" pane.
|
* the "Available" pane.
|
||||||
*
|
*
|
||||||
@ -86,9 +90,9 @@ export class AkDualSelectProvider extends CustomListenerElement(AkControlElement
|
|||||||
this.onNav = this.onNav.bind(this);
|
this.onNav = this.onNav.bind(this);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
this.onSearch = this.onSearch.bind(this);
|
this.onSearch = this.onSearch.bind(this);
|
||||||
this.addCustomListener("ak-pagination-nav-to", this.onNav);
|
this.addEventListener(DualSelectPaginatorNavEvent.eventName, this.onNav);
|
||||||
this.addCustomListener("ak-dual-select-change", this.onChange);
|
this.addEventListener(DualSelectSearchEvent.eventName, this.onSearch);
|
||||||
this.addCustomListener("ak-dual-select-search", this.onSearch);
|
this.addEventListener(DualSelectChangeEvent.eventName, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(changedProperties: PropertyValues<this>) {
|
willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
@ -122,26 +126,16 @@ export class AkDualSelectProvider extends CustomListenerElement(AkControlElement
|
|||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onNav(event: Event) {
|
onNav(event: DualSelectPaginatorNavEvent) {
|
||||||
if (!(event instanceof CustomEvent)) {
|
this.fetch(event.page);
|
||||||
throw new Error(`Expecting a CustomEvent for navigation, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.fetch(event.detail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(event: Event) {
|
onChange(event: DualSelectChangeEvent) {
|
||||||
if (!(event instanceof CustomEvent)) {
|
this.selected = this.internalSelected = event.selected;
|
||||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.internalSelected = event.detail.value;
|
|
||||||
this.selected = this.internalSelected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearch(event: Event) {
|
onSearch(event: DualSelectSearchEvent) {
|
||||||
if (!(event instanceof CustomEvent)) {
|
this.doSearch(event.search);
|
||||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.doSearch(event.detail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearch(search: string) {
|
doSearch(search: string) {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import {
|
import { match } from "ts-pattern";
|
||||||
CustomEmitterElement,
|
|
||||||
CustomListenerElement,
|
|
||||||
} from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { PropertyValues, html, nothing } from "lit";
|
import { PropertyValues, html, nothing } from "lit";
|
||||||
@ -23,15 +20,13 @@ import { AkDualSelectSelectedPane } from "./components/ak-dual-select-selected-p
|
|||||||
import "./components/ak-pagination";
|
import "./components/ak-pagination";
|
||||||
import "./components/ak-search-bar";
|
import "./components/ak-search-bar";
|
||||||
import {
|
import {
|
||||||
EVENT_ADD_ALL,
|
DualSelectChangeEvent,
|
||||||
EVENT_ADD_ONE,
|
DualSelectMoveRequestEvent,
|
||||||
EVENT_ADD_SELECTED,
|
DualSelectPanelSearchEvent,
|
||||||
EVENT_DELETE_ALL,
|
DualSelectSearchEvent,
|
||||||
EVENT_REMOVE_ALL,
|
DualSelectUpdateEvent,
|
||||||
EVENT_REMOVE_ONE,
|
} from "./events";
|
||||||
EVENT_REMOVE_SELECTED,
|
import type { BasePagination, DualSelectPair } from "./types";
|
||||||
} from "./constants";
|
|
||||||
import type { BasePagination, DualSelectPair, SearchbarEvent } from "./types";
|
|
||||||
|
|
||||||
function alphaSort([_k1, v1, s1]: DualSelectPair, [_k2, v2, s2]: DualSelectPair) {
|
function alphaSort([_k1, v1, s1]: DualSelectPair, [_k2, v2, s2]: DualSelectPair) {
|
||||||
const [l, r] = [s1 !== undefined ? s1 : v1, s2 !== undefined ? s2 : v2];
|
const [l, r] = [s1 !== undefined ? s1 : v1, s2 !== undefined ? s2 : v2];
|
||||||
@ -60,7 +55,7 @@ const keyfinder =
|
|||||||
k === key;
|
k === key;
|
||||||
|
|
||||||
@customElement("ak-dual-select")
|
@customElement("ak-dual-select")
|
||||||
export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKElement)) {
|
export class AkDualSelect extends AKElement {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
@ -96,21 +91,9 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
|||||||
super();
|
super();
|
||||||
this.handleMove = this.handleMove.bind(this);
|
this.handleMove = this.handleMove.bind(this);
|
||||||
this.handleSearch = this.handleSearch.bind(this);
|
this.handleSearch = this.handleSearch.bind(this);
|
||||||
[
|
this.addEventListener(DualSelectMoveRequestEvent.eventName, this.handleMove);
|
||||||
EVENT_ADD_ALL,
|
this.addEventListener(DualSelectUpdateEvent.eventName, () => this.requestUpdate());
|
||||||
EVENT_ADD_SELECTED,
|
this.addEventListener(DualSelectPanelSearchEvent.eventName, this.handleSearch);
|
||||||
EVENT_DELETE_ALL,
|
|
||||||
EVENT_REMOVE_ALL,
|
|
||||||
EVENT_REMOVE_SELECTED,
|
|
||||||
EVENT_ADD_ONE,
|
|
||||||
EVENT_REMOVE_ONE,
|
|
||||||
].forEach((eventName: string) => {
|
|
||||||
this.addCustomListener(eventName, (event: Event) => this.handleMove(eventName, event));
|
|
||||||
});
|
|
||||||
this.addCustomListener("ak-dual-select-move", () => {
|
|
||||||
this.requestUpdate();
|
|
||||||
});
|
|
||||||
this.addCustomListener("ak-search", this.handleSearch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(changedProperties: PropertyValues<this>) {
|
willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
@ -123,47 +106,17 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMove(eventName: string, event: Event) {
|
handleMove(event: DualSelectMoveRequestEvent) {
|
||||||
if (!(event instanceof CustomEvent)) {
|
match(event.move)
|
||||||
throw new Error(`Expected move event here, got ${eventName}`);
|
.with("add-all", () => this.addAllVisible())
|
||||||
}
|
.with("add-one", () => this.addOne(event.key))
|
||||||
|
.with("add-selected", () => this.addSelected())
|
||||||
switch (eventName) {
|
.with("delete-all", () => this.removeAll())
|
||||||
case EVENT_ADD_SELECTED: {
|
.with("remove-all", () => this.removeAllVisible())
|
||||||
this.addSelected();
|
.with("remove-one", () => this.removeOne(event.key))
|
||||||
break;
|
.with("remove-selected", () => this.removeSelected())
|
||||||
}
|
.exhaustive();
|
||||||
case EVENT_REMOVE_SELECTED: {
|
this.dispatchEvent(new DualSelectChangeEvent(this.value));
|
||||||
this.removeSelected();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_ADD_ALL: {
|
|
||||||
this.addAllVisible();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_REMOVE_ALL: {
|
|
||||||
this.removeAllVisible();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_DELETE_ALL: {
|
|
||||||
this.removeAll();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_ADD_ONE: {
|
|
||||||
this.addOne(event.detail);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_REMOVE_ONE: {
|
|
||||||
this.removeOne(event.detail);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(
|
|
||||||
`AkDualSelect.handleMove received unknown event type: ${eventName}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.dispatchCustomEvent("ak-dual-select-change", { value: this.value });
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +135,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
|||||||
this.availablePane.value!.clearMove();
|
this.availablePane.value!.clearMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(key: string) {
|
addOne(key?: string) {
|
||||||
|
if (!key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const requested = this.options.find(keyfinder(key));
|
const requested = this.options.find(keyfinder(key));
|
||||||
if (requested && !this.selected.find(keyfinder(requested[0]))) {
|
if (requested && !this.selected.find(keyfinder(requested[0]))) {
|
||||||
this.selected = [...this.selected, requested];
|
this.selected = [...this.selected, requested];
|
||||||
@ -207,7 +163,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
|||||||
this.selectedPane.value!.clearMove();
|
this.selectedPane.value!.clearMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeOne(key: string) {
|
removeOne(key?: string) {
|
||||||
|
if (!key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.selected = this.selected.filter(([k]) => k !== key);
|
this.selected = this.selected.filter(([k]) => k !== key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,18 +182,18 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
|||||||
this.selectedPane.value!.clearMove();
|
this.selectedPane.value!.clearMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearch(event: SearchbarEvent) {
|
handleSearch(event: DualSelectPanelSearchEvent) {
|
||||||
switch (event.detail.source) {
|
switch (event.source) {
|
||||||
case "ak-dual-list-available-search":
|
case "ak-dual-list-available-search":
|
||||||
return this.handleAvailableSearch(event.detail.value);
|
return this.handleAvailableSearch(event.filterOn);
|
||||||
case "ak-dual-list-selected-search":
|
case "ak-dual-list-selected-search":
|
||||||
return this.handleSelectedSearch(event.detail.value);
|
return this.handleSelectedSearch(event.filterOn);
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAvailableSearch(value: string) {
|
handleAvailableSearch(value: string) {
|
||||||
this.dispatchCustomEvent("ak-dual-select-search", value);
|
this.dispatchEvent(new DualSelectSearchEvent(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSelectedSearch(value: string) {
|
handleSelectedSearch(value: string) {
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { bound } from "@goauthentik/elements/decorators/bound";
|
||||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { html, nothing } from "lit";
|
import { html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { classMap } from "lit/directives/class-map.js";
|
import { classMap } from "lit/directives/class-map.js";
|
||||||
import { map } from "lit/directives/map.js";
|
import { map } from "lit/directives/map.js";
|
||||||
|
|
||||||
import { availablePaneStyles, listStyles } from "./styles.css";
|
import { availablePaneStyles } from "./styles.css";
|
||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
|
||||||
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
|
||||||
|
|
||||||
import { EVENT_ADD_ONE } from "../constants";
|
import {
|
||||||
|
DualSelectMoveAvailableEvent,
|
||||||
|
DualSelectMoveRequestEvent,
|
||||||
|
DualSelectUpdateEvent,
|
||||||
|
} from "../events";
|
||||||
import type { DualSelectPair } from "../types";
|
import type { DualSelectPair } from "../types";
|
||||||
|
import { AkDualSelectAbstractPane } from "./ak-dual-select-pane";
|
||||||
const styles = [PFBase, PFButton, PFDualListSelector, listStyles, availablePaneStyles];
|
|
||||||
|
|
||||||
const hostAttributes = [
|
|
||||||
["aria-labelledby", "dual-list-selector-available-pane-status"],
|
|
||||||
["aria-multiselectable", "true"],
|
|
||||||
["role", "listbox"],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @element ak-dual-select-available-panel
|
* @element ak-dual-select-available-panel
|
||||||
@ -40,9 +33,9 @@ const hostAttributes = [
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@customElement("ak-dual-select-available-pane")
|
@customElement("ak-dual-select-available-pane")
|
||||||
export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
export class AkDualSelectAvailablePane extends AkDualSelectAbstractPane {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return [...AkDualSelectAbstractPane.styles, availablePaneStyles];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The array of key/value pairs this pane is currently showing */
|
/* The array of key/value pairs this pane is currently showing */
|
||||||
@ -56,68 +49,31 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
|||||||
@property({ type: Object })
|
@property({ type: Object })
|
||||||
readonly selected: Set<string> = new Set();
|
readonly selected: Set<string> = new Set();
|
||||||
|
|
||||||
/* This is the only mutator for this object. It collects the list of objects the user has
|
@bound
|
||||||
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
|
||||||
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
|
||||||
* moved (removed) if the user so requests.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@state()
|
|
||||||
public toMove: Set<string> = new Set();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.onClick = this.onClick.bind(this);
|
|
||||||
this.onMove = this.onMove.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
hostAttributes.forEach(([attr, value]) => {
|
|
||||||
if (!this.hasAttribute(attr)) {
|
|
||||||
this.setAttribute(attr, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMove() {
|
|
||||||
this.toMove = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick(key: string) {
|
onClick(key: string) {
|
||||||
if (this.selected.has(key)) {
|
if (this.selected.has(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.toMove.has(key)) {
|
this.move(key);
|
||||||
this.toMove.delete(key);
|
this.dispatchEvent(new DualSelectMoveAvailableEvent(this.moveable.sort()));
|
||||||
} else {
|
this.dispatchEvent(new DualSelectUpdateEvent());
|
||||||
this.toMove.add(key);
|
|
||||||
}
|
|
||||||
this.dispatchCustomEvent(
|
|
||||||
"ak-dual-select-available-move-changed",
|
|
||||||
Array.from(this.toMove.values()).sort(),
|
|
||||||
);
|
|
||||||
this.dispatchCustomEvent("ak-dual-select-move");
|
|
||||||
// Necessary because updating a map won't trigger a state change
|
// Necessary because updating a map won't trigger a state change
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bound
|
||||||
onMove(key: string) {
|
onMove(key: string) {
|
||||||
this.toMove.delete(key);
|
this.toMove.delete(key);
|
||||||
this.dispatchCustomEvent(EVENT_ADD_ONE, key);
|
this.dispatchEvent(new DualSelectMoveRequestEvent("add-one", key));
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveable() {
|
|
||||||
return Array.from(this.toMove.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
// DO NOT use `Array.map()` instead of Lit's `map()` function. Lit's `map()` is object-aware and
|
// DO NOT use `Array.map()` instead of Lit's `map()` function. Lit's `map()` is object-aware and
|
||||||
// will not re-arrange or reconstruct the list automatically if the actual sources do not
|
// will not re-arrange or reconstruct the list automatically if the actual sources do not
|
||||||
// change; this allows the available pane to illustrate selected items with the checkmark
|
// change; this allows the available pane to illustrate selected items with the checkmark
|
||||||
// without causing the list to scroll back up to the top.
|
// without causing the list to scroll back up to the top.
|
||||||
|
|
||||||
render() {
|
override render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="pf-c-dual-list-selector__menu">
|
<div class="pf-c-dual-list-selector__menu">
|
||||||
<ul class="pf-c-dual-list-selector__list">
|
<ul class="pf-c-dual-list-selector__list">
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { css, html, nothing } from "lit";
|
import { css, html, nothing } from "lit";
|
||||||
@ -8,13 +7,7 @@ import { customElement, property } from "lit/decorators.js";
|
|||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import {
|
import { DualSelectMoveRequestEvent, type MoveEventType } from "../events";
|
||||||
EVENT_ADD_ALL,
|
|
||||||
EVENT_ADD_SELECTED,
|
|
||||||
EVENT_DELETE_ALL,
|
|
||||||
EVENT_REMOVE_ALL,
|
|
||||||
EVENT_REMOVE_SELECTED,
|
|
||||||
} from "../constants";
|
|
||||||
|
|
||||||
const styles = [
|
const styles = [
|
||||||
PFBase,
|
PFBase,
|
||||||
@ -47,7 +40,7 @@ const styles = [
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@customElement("ak-dual-select-controls")
|
@customElement("ak-dual-select-controls")
|
||||||
export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
export class AkDualSelectControls extends AKElement {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
@ -96,11 +89,11 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
|||||||
this.onClick = this.onClick.bind(this);
|
this.onClick = this.onClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick(eventName: string) {
|
onClick(eventName: MoveEventType) {
|
||||||
this.dispatchCustomEvent(eventName);
|
this.dispatchEvent(new DualSelectMoveRequestEvent(eventName));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderButton(label: string, event: string, active: boolean, direction: string) {
|
renderButton(label: string, event: MoveEventType, active: boolean, direction: string) {
|
||||||
return html`
|
return html`
|
||||||
<div class="pf-c-dual-list-selector__controls-item">
|
<div class="pf-c-dual-list-selector__controls-item">
|
||||||
<button
|
<button
|
||||||
@ -121,23 +114,18 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
|||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="ak-dual-list-selector__controls">
|
<div class="ak-dual-list-selector__controls">
|
||||||
${this.renderButton(
|
${this.renderButton(msg("Add"), "add-selected", this.addActive, "fa-angle-right")}
|
||||||
msg("Add"),
|
|
||||||
EVENT_ADD_SELECTED,
|
|
||||||
this.addActive,
|
|
||||||
"fa-angle-right",
|
|
||||||
)}
|
|
||||||
${this.selectAll
|
${this.selectAll
|
||||||
? html`
|
? html`
|
||||||
${this.renderButton(
|
${this.renderButton(
|
||||||
msg("Add All Available"),
|
msg("Add All Available"),
|
||||||
EVENT_ADD_ALL,
|
"add-all",
|
||||||
this.addAllActive,
|
this.addAllActive,
|
||||||
"fa-angle-double-right",
|
"fa-angle-double-right",
|
||||||
)}
|
)}
|
||||||
${this.renderButton(
|
${this.renderButton(
|
||||||
msg("Remove All Available"),
|
msg("Remove All Available"),
|
||||||
EVENT_REMOVE_ALL,
|
"remove-all",
|
||||||
this.removeAllActive,
|
this.removeAllActive,
|
||||||
"fa-angle-double-left",
|
"fa-angle-double-left",
|
||||||
)}
|
)}
|
||||||
@ -145,14 +133,14 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
|||||||
: nothing}
|
: nothing}
|
||||||
${this.renderButton(
|
${this.renderButton(
|
||||||
msg("Remove"),
|
msg("Remove"),
|
||||||
EVENT_REMOVE_SELECTED,
|
"remove-selected",
|
||||||
this.removeActive,
|
this.removeActive,
|
||||||
"fa-angle-left",
|
"fa-angle-left",
|
||||||
)}
|
)}
|
||||||
${this.deleteAll
|
${this.deleteAll
|
||||||
? html`${this.renderButton(
|
? html`${this.renderButton(
|
||||||
msg("Remove All"),
|
msg("Remove All"),
|
||||||
EVENT_DELETE_ALL,
|
"delete-all",
|
||||||
this.enableDeleteAll,
|
this.enableDeleteAll,
|
||||||
"fa-times",
|
"fa-times",
|
||||||
)}`
|
)}`
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
|
import { TemplateResult } from "lit";
|
||||||
|
import { state } from "lit/decorators.js";
|
||||||
|
|
||||||
|
import { listStyles } from "./styles.css";
|
||||||
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
|
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
||||||
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
|
const styles = [PFBase, PFButton, PFDualListSelector, listStyles];
|
||||||
|
|
||||||
|
const hostAttributes = [
|
||||||
|
["aria-labelledby", "dual-list-selector-selected-pane-status"],
|
||||||
|
["aria-multiselectable", "true"],
|
||||||
|
["role", "listbox"],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @element ak-dual-select-panel
|
||||||
|
*
|
||||||
|
* The "selected options" or "right" pane in a dual-list multi-select. It receives from its parent
|
||||||
|
* a list of the selected options, and maintains an internal list of objects selected to move.
|
||||||
|
*
|
||||||
|
* @fires ak-dual-select-selected-move-changed - When the list of "to move" entries changed.
|
||||||
|
* Includes the current `toMove` content.
|
||||||
|
*
|
||||||
|
* @fires ak-dual-select-remove-one - Double-click with the element clicked on.
|
||||||
|
*
|
||||||
|
* It is not expected that the `ak-dual-select-selected-move-changed` will be used; instead, the
|
||||||
|
* attribute will be read by the parent when a control is clicked.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export abstract class AkDualSelectAbstractPane extends AKElement {
|
||||||
|
static get styles() {
|
||||||
|
return styles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the only mutator for this object. It collects the list of objects the user has
|
||||||
|
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
||||||
|
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
||||||
|
* moved (removed) if the user so requests.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@state()
|
||||||
|
public toMove: Set<string> = new Set();
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
hostAttributes.forEach(([attr, value]) => {
|
||||||
|
if (!this.hasAttribute(attr)) {
|
||||||
|
this.setAttribute(attr, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMove() {
|
||||||
|
this.toMove = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
move(key: string) {
|
||||||
|
if (this.toMove.has(key)) {
|
||||||
|
this.toMove.delete(key);
|
||||||
|
} else {
|
||||||
|
this.toMove.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get moveable() {
|
||||||
|
return Array.from(this.toMove.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract render(): TemplateResult;
|
||||||
|
}
|
@ -1,26 +1,19 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { bound } from "@goauthentik/elements/decorators/bound";
|
||||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { html } from "lit";
|
import { html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { classMap } from "lit/directives/class-map.js";
|
import { classMap } from "lit/directives/class-map.js";
|
||||||
import { map } from "lit/directives/map.js";
|
import { map } from "lit/directives/map.js";
|
||||||
|
|
||||||
import { listStyles, selectedPaneStyles } from "./styles.css";
|
import { selectedPaneStyles } from "./styles.css";
|
||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
|
||||||
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
|
||||||
|
|
||||||
import { EVENT_REMOVE_ONE } from "../constants";
|
import {
|
||||||
|
DualSelectMoveRequestEvent,
|
||||||
|
DualSelectMoveSelectedEvent,
|
||||||
|
DualSelectUpdateEvent,
|
||||||
|
} from "../events";
|
||||||
import type { DualSelectPair } from "../types";
|
import type { DualSelectPair } from "../types";
|
||||||
|
import { AkDualSelectAbstractPane } from "./ak-dual-select-pane";
|
||||||
const styles = [PFBase, PFButton, PFDualListSelector, listStyles, selectedPaneStyles];
|
|
||||||
|
|
||||||
const hostAttributes = [
|
|
||||||
["aria-labelledby", "dual-list-selector-selected-pane-status"],
|
|
||||||
["aria-multiselectable", "true"],
|
|
||||||
["role", "listbox"],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @element ak-dual-select-available-panel
|
* @element ak-dual-select-available-panel
|
||||||
@ -38,70 +31,32 @@ const hostAttributes = [
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@customElement("ak-dual-select-selected-pane")
|
@customElement("ak-dual-select-selected-pane")
|
||||||
export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
|
export class AkDualSelectSelectedPane extends AkDualSelectAbstractPane {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return [...AkDualSelectAbstractPane.styles, selectedPaneStyles];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The array of key/value pairs that are in the selected list. ALL of them. */
|
/* The array of key/value pairs that are in the selected list. ALL of them. */
|
||||||
@property({ type: Array })
|
@property({ type: Array })
|
||||||
readonly selected: DualSelectPair[] = [];
|
readonly selected: DualSelectPair[] = [];
|
||||||
|
|
||||||
/*
|
@bound
|
||||||
* This is the only mutator for this object. It collects the list of objects the user has
|
|
||||||
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
|
||||||
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
|
||||||
* moved (removed) if the user so requests.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@state()
|
|
||||||
public toMove: Set<string> = new Set();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.onClick = this.onClick.bind(this);
|
|
||||||
this.onMove = this.onMove.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
hostAttributes.forEach(([attr, value]) => {
|
|
||||||
if (!this.hasAttribute(attr)) {
|
|
||||||
this.setAttribute(attr, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMove() {
|
|
||||||
this.toMove = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick(key: string) {
|
onClick(key: string) {
|
||||||
if (this.toMove.has(key)) {
|
this.move(key);
|
||||||
this.toMove.delete(key);
|
this.dispatchEvent(new DualSelectMoveSelectedEvent(this.moveable.sort()));
|
||||||
} else {
|
this.dispatchEvent(new DualSelectUpdateEvent());
|
||||||
this.toMove.add(key);
|
|
||||||
}
|
|
||||||
this.dispatchCustomEvent(
|
|
||||||
"ak-dual-select-selected-move-changed",
|
|
||||||
Array.from(this.toMove.values()).sort(),
|
|
||||||
);
|
|
||||||
this.dispatchCustomEvent("ak-dual-select-move");
|
|
||||||
// Necessary because updating a map won't trigger a state change
|
// Necessary because updating a map won't trigger a state change
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bound
|
||||||
onMove(key: string) {
|
onMove(key: string) {
|
||||||
this.toMove.delete(key);
|
this.toMove.delete(key);
|
||||||
this.dispatchCustomEvent(EVENT_REMOVE_ONE, key);
|
this.dispatchEvent(new DualSelectMoveRequestEvent("remove-one", key));
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveable() {
|
override render() {
|
||||||
return Array.from(this.toMove.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
return html`
|
||||||
<div class="pf-c-dual-list-selector__menu">
|
<div class="pf-c-dual-list-selector__menu">
|
||||||
<ul class="pf-c-dual-list-selector__list">
|
<ul class="pf-c-dual-list-selector__list">
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { css, html, nothing } from "lit";
|
import { css, html, nothing } from "lit";
|
||||||
@ -9,6 +8,7 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
|||||||
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
|
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
|
import { DualSelectPaginatorNavEvent } from "../events";
|
||||||
import type { BasePagination } from "../types";
|
import type { BasePagination } from "../types";
|
||||||
|
|
||||||
const styles = [
|
const styles = [
|
||||||
@ -27,7 +27,7 @@ const styles = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
@customElement("ak-pagination")
|
@customElement("ak-pagination")
|
||||||
export class AkPagination extends CustomEmitterElement(AKElement) {
|
export class AkPagination extends AKElement {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ export class AkPagination extends CustomEmitterElement(AKElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClick(nav: number | undefined) {
|
onClick(nav: number | undefined) {
|
||||||
this.dispatchCustomEvent("ak-pagination-nav-to", nav ?? 0);
|
this.dispatchEvent(new DualSelectPaginatorNavEvent(nav ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
|
||||||
|
|
||||||
import { html } from "lit";
|
import { html } from "lit";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
@ -9,12 +8,12 @@ import type { Ref } from "lit/directives/ref.js";
|
|||||||
import { globalVariables, searchStyles } from "./search.css";
|
import { globalVariables, searchStyles } from "./search.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import type { SearchbarEvent } from "../types";
|
import { DualSelectPanelSearchEvent } from "../events";
|
||||||
|
|
||||||
const styles = [PFBase, globalVariables, searchStyles];
|
const styles = [PFBase, globalVariables, searchStyles];
|
||||||
|
|
||||||
@customElement("ak-search-bar")
|
@customElement("ak-search-bar")
|
||||||
export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
export class AkSearchbar extends AKElement {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
@ -40,10 +39,7 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
|||||||
if (this.input.value) {
|
if (this.input.value) {
|
||||||
this.value = this.input.value.value;
|
this.value = this.input.value.value;
|
||||||
}
|
}
|
||||||
this.dispatchCustomEvent<SearchbarEvent>("ak-search", {
|
this.dispatchEvent(new DualSelectPanelSearchEvent(this.name, this.value));
|
||||||
source: this.name,
|
|
||||||
value: this.value,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
112
web/src/elements/ak-dual-select/events.ts
Normal file
112
web/src/elements/ak-dual-select/events.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { DualSelectPair } from "./types";
|
||||||
|
|
||||||
|
// Handled by the Server layer provider
|
||||||
|
|
||||||
|
// Request to provide a different page of the paginated results in the "available" panel.
|
||||||
|
export class DualSelectPaginatorNavEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-paginator-nav";
|
||||||
|
constructor(public page: number = 0) {
|
||||||
|
super(DualSelectPaginatorNavEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to provide a filtered collection for the "available" panel via a search string
|
||||||
|
export class DualSelectSearchEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-search";
|
||||||
|
constructor(public search: string) {
|
||||||
|
super(DualSelectSearchEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to update the "selected" list in the provider
|
||||||
|
export class DualSelectChangeEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-change";
|
||||||
|
constructor(public selected: DualSelectPair[]) {
|
||||||
|
super(DualSelectChangeEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paginator and specific item events
|
||||||
|
|
||||||
|
export const moveEvents = [
|
||||||
|
"add-all",
|
||||||
|
"add-one",
|
||||||
|
"add-selected",
|
||||||
|
"delete-all",
|
||||||
|
"remove-all",
|
||||||
|
"remove-one",
|
||||||
|
"remove-selected",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type MoveEventType = (typeof moveEvents)[number];
|
||||||
|
|
||||||
|
// Request to add or remove all, some, or just one item from the "selected" panel
|
||||||
|
export class DualSelectMoveRequestEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-request-move";
|
||||||
|
constructor(
|
||||||
|
public move: MoveEventType,
|
||||||
|
public key?: string,
|
||||||
|
) {
|
||||||
|
super(DualSelectMoveRequestEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update events
|
||||||
|
|
||||||
|
// Request to update the viewset
|
||||||
|
export class DualSelectUpdateEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-update";
|
||||||
|
constructor() {
|
||||||
|
super(DualSelectUpdateEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DualSelectMoveChangedEvent {
|
||||||
|
keys: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to update the list of "marked for move" items in the "available" panel
|
||||||
|
export class DualSelectMoveAvailableEvent extends Event implements DualSelectMoveChangedEvent {
|
||||||
|
static readonly eventName = "ak-dual-select-move-available";
|
||||||
|
constructor(public keys: string[]) {
|
||||||
|
super(DualSelectMoveAvailableEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to update the list of "marked for move" items in the "selected" panel
|
||||||
|
export class DualSelectMoveSelectedEvent extends Event implements DualSelectMoveChangedEvent {
|
||||||
|
static readonly eventName = "ak-dual-select-move-selected";
|
||||||
|
constructor(public keys: string[]) {
|
||||||
|
super(DualSelectMoveSelectedEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to update either panel with a Filter
|
||||||
|
export class DualSelectPanelSearchEvent extends Event {
|
||||||
|
static readonly eventName = "ak-dual-select-panel-search";
|
||||||
|
constructor(
|
||||||
|
public source: string,
|
||||||
|
public filterOn: string,
|
||||||
|
) {
|
||||||
|
super(DualSelectPanelSearchEvent.eventName, { bubbles: true, composed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementEventMap {
|
||||||
|
[DualSelectUpdateEvent.eventName]: DualSelectUpdateEvent;
|
||||||
|
[DualSelectMoveAvailableEvent.eventName]: DualSelectMoveAvailableEvent;
|
||||||
|
[DualSelectMoveSelectedEvent.eventName]: DualSelectMoveSelectedEvent;
|
||||||
|
[DualSelectMoveRequestEvent.eventName]: DualSelectMoveRequestEvent;
|
||||||
|
[DualSelectPaginatorNavEvent.eventName]: DualSelectPaginatorNavEvent;
|
||||||
|
[DualSelectSearchEvent.eventName]: DualSelectSearchEvent;
|
||||||
|
[DualSelectChangeEvent.eventName]: DualSelectChangeEvent;
|
||||||
|
[DualSelectPanelSearchEvent.eventName]: DualSelectPanelSearchEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WindowEventMap {
|
||||||
|
[DualSelectMoveRequestEvent.eventName]: DualSelectMoveRequestEvent;
|
||||||
|
[DualSelectPaginatorNavEvent.eventName]: DualSelectPaginatorNavEvent;
|
||||||
|
[DualSelectMoveSelectedEvent.eventName]: DualSelectMoveSelectedEvent;
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import { TemplateResult, html } from "lit";
|
|||||||
|
|
||||||
import "../components/ak-dual-select-available-pane";
|
import "../components/ak-dual-select-available-pane";
|
||||||
import { AkDualSelectAvailablePane } from "../components/ak-dual-select-available-pane";
|
import { AkDualSelectAvailablePane } from "../components/ak-dual-select-available-pane";
|
||||||
|
import { DualSelectMoveSelectedEvent } from "../events";
|
||||||
import "./sb-host-provider";
|
import "./sb-host-provider";
|
||||||
|
|
||||||
const metadata: Meta<AkDualSelectAvailablePane> = {
|
const metadata: Meta<AkDualSelectAvailablePane> = {
|
||||||
@ -53,15 +54,15 @@ const container = (testItem: TemplateResult) =>
|
|||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const handleMoveChanged = (result: any) => {
|
const handleMoveChanged = (result: DualSelectMoveSelectedEvent) => {
|
||||||
const target = document.querySelector("#action-button-message-pad");
|
const target = document.querySelector("#action-button-message-pad");
|
||||||
target!.innerHTML = "";
|
target!.innerHTML = "";
|
||||||
result.detail.forEach((key: string) => {
|
result.keys.forEach((key: string) => {
|
||||||
target!.append(new DOMParser().parseFromString(`<li>${key}</li>`, "text/xml").firstChild!);
|
target!.append(new DOMParser().parseFromString(`<li>${key}</li>`, "text/xml").firstChild!);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("ak-dual-select-available-move-changed", handleMoveChanged);
|
window.addEventListener(DualSelectMoveSelectedEvent.eventName, handleMoveChanged);
|
||||||
|
|
||||||
type Story = StoryObj;
|
type Story = StoryObj;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { TemplateResult, html } from "lit";
|
|||||||
|
|
||||||
import "../components/ak-dual-select-controls";
|
import "../components/ak-dual-select-controls";
|
||||||
import { AkDualSelectControls } from "../components/ak-dual-select-controls";
|
import { AkDualSelectControls } from "../components/ak-dual-select-controls";
|
||||||
|
import { DualSelectMoveRequestEvent } from "../events";
|
||||||
|
|
||||||
const metadata: Meta<AkDualSelectControls> = {
|
const metadata: Meta<AkDualSelectControls> = {
|
||||||
title: "Elements / Dual Select / Control Panel",
|
title: "Elements / Dual Select / Control Panel",
|
||||||
@ -59,10 +60,9 @@ const displayMessage = (result: any) => {
|
|||||||
target!.appendChild(doc.firstChild!);
|
target!.appendChild(doc.firstChild!);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("ak-dual-select-add", () => displayMessage("add"));
|
window.addEventListener(DualSelectMoveRequestEvent.eventName, (ev: DualSelectMoveRequestEvent) =>
|
||||||
window.addEventListener("ak-dual-select-remove", () => displayMessage("remove"));
|
displayMessage(ev.move.toString()),
|
||||||
window.addEventListener("ak-dual-select-add-all", () => displayMessage("add all"));
|
);
|
||||||
window.addEventListener("ak-dual-select-remove-all", () => displayMessage("remove all"));
|
|
||||||
|
|
||||||
type Story = StoryObj;
|
type Story = StoryObj;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import { Pagination } from "@goauthentik/api";
|
|||||||
|
|
||||||
import "../ak-dual-select";
|
import "../ak-dual-select";
|
||||||
import { AkDualSelect } from "../ak-dual-select";
|
import { AkDualSelect } from "../ak-dual-select";
|
||||||
|
import { DualSelectPaginatorNavEvent } from "../events";
|
||||||
import type { DualSelectPair } from "../types";
|
import type { DualSelectPair } from "../types";
|
||||||
|
|
||||||
const goodForYouRaw = `
|
const goodForYouRaw = `
|
||||||
@ -83,11 +84,11 @@ export class AkSbFruity extends LitElement {
|
|||||||
totalPages: Math.ceil(this.options.length / this.pageLength),
|
totalPages: Math.ceil(this.options.length / this.pageLength),
|
||||||
};
|
};
|
||||||
this.onNavigation = this.onNavigation.bind(this);
|
this.onNavigation = this.onNavigation.bind(this);
|
||||||
this.addEventListener("ak-pagination-nav-to", this.onNavigation);
|
this.addEventListener(DualSelectPaginatorNavEvent.eventName, this.onNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
onNavigation(evt: Event) {
|
onNavigation(evt: DualSelectPaginatorNavEvent) {
|
||||||
const current: number = (evt as CustomEvent).detail;
|
const current = evt.page;
|
||||||
const index = current - 1;
|
const index = current - 1;
|
||||||
if (index * this.pageLength > this.options.length) {
|
if (index * this.pageLength > this.options.length) {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user