Compare commits
25 Commits
version/0.
...
version-0.
Author | SHA1 | Date | |
---|---|---|---|
897e0f90fe | |||
ecbcd86f05 | |||
65d9f690cd | |||
f96c2db5df | |||
5647f53140 | |||
4e20cd0fee | |||
49636f8fa0 | |||
cd8157ea08 | |||
2a94ad7782 | |||
07eb5ffb4b | |||
8cc68928b8 | |||
221db12f85 | |||
34166d3c20 | |||
94972d64e6 | |||
253eaa382c | |||
fc4f9733d1 | |||
8d784afcd1 | |||
e23afd18e4 | |||
c2a30b760a | |||
6e24856d45 | |||
98a58b74e3 | |||
5f3ab22bea | |||
1ed5d5da35 | |||
76193e0031 | |||
50109ca7ad |
@ -1,5 +1,5 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 0.13.2-stable
|
current_version = 0.13.5-stable
|
||||||
tag = True
|
tag = True
|
||||||
commit = True
|
commit = True
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
|
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
|
||||||
|
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@ -18,11 +18,11 @@ jobs:
|
|||||||
- name: Building Docker Image
|
- name: Building Docker Image
|
||||||
run: docker build
|
run: docker build
|
||||||
--no-cache
|
--no-cache
|
||||||
-t beryju/authentik:0.13.2-stable
|
-t beryju/authentik:0.13.5-stable
|
||||||
-t beryju/authentik:latest
|
-t beryju/authentik:latest
|
||||||
-f Dockerfile .
|
-f Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/authentik:0.13.2-stable
|
run: docker push beryju/authentik:0.13.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/authentik:latest
|
run: docker push beryju/authentik:latest
|
||||||
build-proxy:
|
build-proxy:
|
||||||
@ -48,11 +48,11 @@ jobs:
|
|||||||
cd proxy/
|
cd proxy/
|
||||||
docker build \
|
docker build \
|
||||||
--no-cache \
|
--no-cache \
|
||||||
-t beryju/authentik-proxy:0.13.2-stable \
|
-t beryju/authentik-proxy:0.13.5-stable \
|
||||||
-t beryju/authentik-proxy:latest \
|
-t beryju/authentik-proxy:latest \
|
||||||
-f Dockerfile .
|
-f Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/authentik-proxy:0.13.2-stable
|
run: docker push beryju/authentik-proxy:0.13.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/authentik-proxy:latest
|
run: docker push beryju/authentik-proxy:latest
|
||||||
build-static:
|
build-static:
|
||||||
@ -69,11 +69,11 @@ jobs:
|
|||||||
cd web/
|
cd web/
|
||||||
docker build \
|
docker build \
|
||||||
--no-cache \
|
--no-cache \
|
||||||
-t beryju/authentik-static:0.13.2-stable \
|
-t beryju/authentik-static:0.13.5-stable \
|
||||||
-t beryju/authentik-static:latest \
|
-t beryju/authentik-static:latest \
|
||||||
-f Dockerfile .
|
-f Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/authentik-static:0.13.2-stable
|
run: docker push beryju/authentik-static:0.13.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/authentik-static:latest
|
run: docker push beryju/authentik-static:latest
|
||||||
test-release:
|
test-release:
|
||||||
@ -107,5 +107,5 @@ jobs:
|
|||||||
SENTRY_PROJECT: authentik
|
SENTRY_PROJECT: authentik
|
||||||
SENTRY_URL: https://sentry.beryju.org
|
SENTRY_URL: https://sentry.beryju.org
|
||||||
with:
|
with:
|
||||||
tagName: 0.13.2-stable
|
tagName: 0.13.5-stable
|
||||||
environment: beryjuorg-prod
|
environment: beryjuorg-prod
|
||||||
|
12
Pipfile.lock
generated
12
Pipfile.lock
generated
@ -74,18 +74,18 @@
|
|||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:18d7ba5d623d4794f439201ab900c9c14a50019bc52d9113b0a2bb2e1ef9af2c",
|
"sha256:a05614300fd404c7952a55ae92e106b9400ae65886425aaab3104527be833848",
|
||||||
"sha256:1ddfd307d409e7bc792bd12923078f59c2f56fbba4065c320b3f768481bbbbf7"
|
"sha256:c7556b0861d982b71043fbc0df024644320c817ad796391c442d0c2f15a77223"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.16.38"
|
"version": "==1.16.39"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:1f1ecb1b0c6ffc8fcdd5eeb40f33e986dfe9724dc66c83017014a0506af6378a",
|
"sha256:449e4196160ff58ee27d2a626a7ce4cfff2640fe1806d7a279e73a30ad286347",
|
||||||
"sha256:38ccc132c5b9d1e7a4dd37af78061fd2dd0e4fd611f527b409a4e9a679a85cdb"
|
"sha256:e0d0386098a072abd7b6c087e6149d997377c969a823ebe01b3f5bfabe9bfac0"
|
||||||
],
|
],
|
||||||
"version": "==1.19.38"
|
"version": "==1.19.39"
|
||||||
},
|
},
|
||||||
"cachetools": {
|
"cachetools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
"""authentik"""
|
"""authentik"""
|
||||||
__version__ = "0.13.2-stable"
|
__version__ = "0.13.5-stable"
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
<div slot="modal"></div>
|
<div slot="modal"></div>
|
||||||
</ak-modal-button>
|
</ak-modal-button>
|
||||||
<ak-modal-button href="{% url 'authentik_admin:policy-test' pk=policy.pk %}">
|
<ak-modal-button href="{% url 'authentik_admin:policy-test' pk=policy.pk %}">
|
||||||
<ak-spinner-button slot="trigger" class="pf-m-tertiary">
|
<ak-spinner-button slot="trigger" class="pf-m-secondary">
|
||||||
{% trans 'Test' %}
|
{% trans 'Test' %}
|
||||||
</ak-spinner-button>
|
</ak-spinner-button>
|
||||||
<div slot="modal"></div>
|
<div slot="modal"></div>
|
||||||
|
@ -37,8 +37,9 @@
|
|||||||
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
|
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
|
||||||
<thead>
|
<thead>
|
||||||
<tr role="row">
|
<tr role="row">
|
||||||
|
<th role="columnheader" scope="col">{% trans 'ID' %}</th>
|
||||||
|
<th role="columnheader" scope="col">{% trans 'Created by' %}</th>
|
||||||
<th role="columnheader" scope="col">{% trans 'Expiry' %}</th>
|
<th role="columnheader" scope="col">{% trans 'Expiry' %}</th>
|
||||||
<th role="columnheader" scope="col">{% trans 'Link' %}</th>
|
|
||||||
<th role="cell"></th>
|
<th role="cell"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -47,12 +48,17 @@
|
|||||||
<tr role="row">
|
<tr role="row">
|
||||||
<td role="cell">
|
<td role="cell">
|
||||||
<span>
|
<span>
|
||||||
{{ invitation.expiry }}
|
{{ invitation.invite_uuid }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td role="cell">
|
<td role="cell">
|
||||||
<span>
|
<span>
|
||||||
{{ invitation.Link }}
|
{{ invitation.created_by }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td role="cell">
|
||||||
|
<span>
|
||||||
|
{{ invitation.expiry|default:"-" }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -13,6 +13,7 @@ from rest_framework_guardian.filters import ObjectPermissionsFilter
|
|||||||
|
|
||||||
from authentik.admin.api.metrics import get_events_per_1h
|
from authentik.admin.api.metrics import get_events_per_1h
|
||||||
from authentik.audit.models import EventAction
|
from authentik.audit.models import EventAction
|
||||||
|
from authentik.core.api.providers import ProviderSerializer
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
from authentik.policies.engine import PolicyEngine
|
from authentik.policies.engine import PolicyEngine
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ class ApplicationSerializer(ModelSerializer):
|
|||||||
"""Application Serializer"""
|
"""Application Serializer"""
|
||||||
|
|
||||||
launch_url = SerializerMethodField()
|
launch_url = SerializerMethodField()
|
||||||
|
provider = ProviderSerializer(source="get_provider", required=False)
|
||||||
|
|
||||||
def get_launch_url(self, instance: Application) -> str:
|
def get_launch_url(self, instance: Application) -> str:
|
||||||
"""Get generated launch URL"""
|
"""Get generated launch URL"""
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""User API Views"""
|
"""User API Views"""
|
||||||
from drf_yasg2.utils import swagger_auto_schema
|
from drf_yasg2.utils import swagger_auto_schema
|
||||||
|
from guardian.utils import get_anonymous_user
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
@ -33,9 +34,12 @@ class UserSerializer(ModelSerializer):
|
|||||||
class UserViewSet(ModelViewSet):
|
class UserViewSet(ModelViewSet):
|
||||||
"""User Viewset"""
|
"""User Viewset"""
|
||||||
|
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all().exclude(pk=get_anonymous_user().pk)
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return User.objects.all().exclude(pk=get_anonymous_user().pk)
|
||||||
|
|
||||||
@swagger_auto_schema(responses={200: UserSerializer(many=False)})
|
@swagger_auto_schema(responses={200: UserSerializer(many=False)})
|
||||||
@action(detail=False)
|
@action(detail=False)
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
@ -3,6 +3,15 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load authentik_utils %}
|
{% load authentik_utils %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
{{ block.super }}
|
||||||
|
<style>
|
||||||
|
.pf-c-empty-state {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<section class="pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
|
<section class="pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
|
||||||
<div class="pf-c-empty-state">
|
<div class="pf-c-empty-state">
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<p class="pf-c-form__helper-text">{{ field.help_text }}</p>
|
<p class="pf-c-form__helper-text">{{ field.help_text }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% elif field.field.widget|fieldtype == 'Select' %}
|
{% elif field.field.widget|fieldtype == 'Select' or field.field.widget|fieldtype == "SelectMultiple" %}
|
||||||
<div class="pf-c-form__group-label">
|
<div class="pf-c-form__group-label">
|
||||||
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
|
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
|
||||||
<span class="pf-c-form__label-text">{{ field.label }}</span>
|
<span class="pf-c-form__label-text">{{ field.label }}</span>
|
||||||
@ -46,6 +46,9 @@
|
|||||||
{% if field.help_text %}
|
{% if field.help_text %}
|
||||||
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
|
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if field.field.widget|fieldtype == 'SelectMultiple' %}
|
||||||
|
<p class="pf-c-form__helper-text">{% trans 'Hold control/command to select multiple items.' %}</p>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
|
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
|
||||||
|
@ -94,11 +94,6 @@ class TokenCreateView(
|
|||||||
success_url = reverse_lazy("authentik_core:user-tokens")
|
success_url = reverse_lazy("authentik_core:user-tokens")
|
||||||
success_message = _("Successfully created Token")
|
success_message = _("Successfully created Token")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
||||||
kwargs = super().get_context_data(**kwargs)
|
|
||||||
kwargs["container_template"] = "user/base.html"
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def form_valid(self, form: UserTokenForm) -> HttpResponse:
|
def form_valid(self, form: UserTokenForm) -> HttpResponse:
|
||||||
form.instance.user = self.request.user
|
form.instance.user = self.request.user
|
||||||
form.instance.intent = TokenIntents.INTENT_API
|
form.instance.intent = TokenIntents.INTENT_API
|
||||||
@ -112,21 +107,16 @@ class TokenUpdateView(
|
|||||||
|
|
||||||
model = Token
|
model = Token
|
||||||
form_class = UserTokenForm
|
form_class = UserTokenForm
|
||||||
permission_required = "authentik_core.update_token"
|
permission_required = "authentik_core.change_token"
|
||||||
template_name = "generic/update.html"
|
template_name = "generic/update.html"
|
||||||
success_url = reverse_lazy("authentik_core:user-tokens")
|
success_url = reverse_lazy("authentik_core:user-tokens")
|
||||||
success_message = _("Successfully updated Token")
|
success_message = _("Successfully updated Token")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
||||||
kwargs = super().get_context_data(**kwargs)
|
|
||||||
kwargs["container_template"] = "user/base.html"
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def get_object(self) -> Token:
|
def get_object(self) -> Token:
|
||||||
identifier = self.kwargs.get("identifier")
|
identifier = self.kwargs.get("identifier")
|
||||||
return get_objects_for_user(
|
return get_objects_for_user(
|
||||||
self.request.user, "authentik_core.update_token", self.model
|
self.request.user, self.permission_required, self.model
|
||||||
).filter(intent=TokenIntents.INTENT_API, identifier=identifier)
|
).filter(intent=TokenIntents.INTENT_API, identifier=identifier).first()
|
||||||
|
|
||||||
|
|
||||||
class TokenDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessageView):
|
class TokenDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessageView):
|
||||||
@ -138,7 +128,8 @@ class TokenDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessage
|
|||||||
success_url = reverse_lazy("authentik_core:user-tokens")
|
success_url = reverse_lazy("authentik_core:user-tokens")
|
||||||
success_message = _("Successfully deleted Token")
|
success_message = _("Successfully deleted Token")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
def get_object(self) -> Token:
|
||||||
kwargs = super().get_context_data(**kwargs)
|
identifier = self.kwargs.get("identifier")
|
||||||
kwargs["container_template"] = "user/base.html"
|
return get_objects_for_user(
|
||||||
return kwargs
|
self.request.user, self.permission_required, self.model
|
||||||
|
).filter(intent=TokenIntents.INTENT_API, identifier=identifier).first()
|
||||||
|
@ -19,6 +19,7 @@ LOGGER = get_logger()
|
|||||||
|
|
||||||
PLAN_CONTEXT_PENDING_USER = "pending_user"
|
PLAN_CONTEXT_PENDING_USER = "pending_user"
|
||||||
PLAN_CONTEXT_SSO = "is_sso"
|
PLAN_CONTEXT_SSO = "is_sso"
|
||||||
|
PLAN_CONTEXT_REDIRECT = "redirect"
|
||||||
PLAN_CONTEXT_APPLICATION = "application"
|
PLAN_CONTEXT_APPLICATION = "application"
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,12 @@ from authentik.audit.models import cleanse_dict
|
|||||||
from authentik.core.models import USER_ATTRIBUTE_DEBUG
|
from authentik.core.models import USER_ATTRIBUTE_DEBUG
|
||||||
from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException
|
from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException
|
||||||
from authentik.flows.models import ConfigurableStage, Flow, FlowDesignation, Stage
|
from authentik.flows.models import ConfigurableStage, Flow, FlowDesignation, Stage
|
||||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan, FlowPlanner
|
from authentik.flows.planner import (
|
||||||
|
PLAN_CONTEXT_PENDING_USER,
|
||||||
|
PLAN_CONTEXT_REDIRECT,
|
||||||
|
FlowPlan,
|
||||||
|
FlowPlanner,
|
||||||
|
)
|
||||||
from authentik.lib.utils.reflection import class_to_path
|
from authentik.lib.utils.reflection import class_to_path
|
||||||
from authentik.lib.utils.urls import is_url_absolute, redirect_with_qs
|
from authentik.lib.utils.urls import is_url_absolute, redirect_with_qs
|
||||||
from authentik.policies.http import AccessDeniedResponse
|
from authentik.policies.http import AccessDeniedResponse
|
||||||
@ -145,9 +150,13 @@ class FlowExecutorView(View):
|
|||||||
"""User Successfully passed all stages"""
|
"""User Successfully passed all stages"""
|
||||||
# Since this is wrapped by the ExecutorShell, the next argument is saved in the session
|
# Since this is wrapped by the ExecutorShell, the next argument is saved in the session
|
||||||
# extract the next param before cancel as that cleans it
|
# extract the next param before cancel as that cleans it
|
||||||
next_param = self.request.session.get(SESSION_KEY_GET, {}).get(
|
next_param = None
|
||||||
NEXT_ARG_NAME, "authentik_core:shell"
|
if self.plan:
|
||||||
)
|
next_param = self.plan.context.get(PLAN_CONTEXT_REDIRECT)
|
||||||
|
if not next_param:
|
||||||
|
next_param = self.request.session.get(SESSION_KEY_GET, {}).get(
|
||||||
|
NEXT_ARG_NAME, "authentik_core:shell"
|
||||||
|
)
|
||||||
self.cancel()
|
self.cancel()
|
||||||
return to_stage_response(self.request, redirect_with_qs(next_param))
|
return to_stage_response(self.request, redirect_with_qs(next_param))
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
"""Outpost forms"""
|
"""Outpost forms"""
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from kubernetes.client.configuration import Configuration
|
||||||
|
from kubernetes.config.config_exception import ConfigException
|
||||||
|
from kubernetes.config.kube_config import load_kube_config_from_dict
|
||||||
|
|
||||||
from authentik.admin.fields import CodeMirrorWidget, YAMLField
|
from authentik.admin.fields import CodeMirrorWidget, YAMLField
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
@ -71,6 +75,23 @@ class DockerServiceConnectionForm(forms.ModelForm):
|
|||||||
class KubernetesServiceConnectionForm(forms.ModelForm):
|
class KubernetesServiceConnectionForm(forms.ModelForm):
|
||||||
"""Kubernetes service-connection form"""
|
"""Kubernetes service-connection form"""
|
||||||
|
|
||||||
|
def clean_kubeconfig(self):
|
||||||
|
"""Validate kubeconfig by attempting to load it"""
|
||||||
|
kubeconfig = self.cleaned_data["kubeconfig"]
|
||||||
|
if kubeconfig == {}:
|
||||||
|
if not self.cleaned_data["local"]:
|
||||||
|
raise ValidationError(
|
||||||
|
_("You can only use an empty kubeconfig when local is enabled.")
|
||||||
|
)
|
||||||
|
# Empty kubeconfig is valid
|
||||||
|
return kubeconfig
|
||||||
|
config = Configuration()
|
||||||
|
try:
|
||||||
|
load_kube_config_from_dict(kubeconfig, client_configuration=config)
|
||||||
|
except ConfigException:
|
||||||
|
raise ValidationError(_("Invalid kubeconfig"))
|
||||||
|
return kubeconfig
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = KubernetesServiceConnection
|
model = KubernetesServiceConnection
|
||||||
|
21
authentik/outposts/migrations/0015_auto_20201224_1206.py
Normal file
21
authentik/outposts/migrations/0015_auto_20201224_1206.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.1.4 on 2020-12-24 12:06
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_outposts", "0014_auto_20201213_1407"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="kubernetesserviceconnection",
|
||||||
|
name="kubeconfig",
|
||||||
|
field=models.JSONField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Paste your kubeconfig here. authentik will automatically use the currently selected context.",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -234,7 +234,8 @@ class KubernetesServiceConnection(OutpostServiceConnection):
|
|||||||
"Paste your kubeconfig here. authentik will automatically use "
|
"Paste your kubeconfig here. authentik will automatically use "
|
||||||
"the currently selected context."
|
"the currently selected context."
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -21,6 +21,7 @@ class PolicyEvaluator(BaseEvaluator):
|
|||||||
def __init__(self, policy_name: str):
|
def __init__(self, policy_name: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._messages = []
|
self._messages = []
|
||||||
|
self._context["ak_logger"] = get_logger(policy_name)
|
||||||
self._context["ak_message"] = self.expr_func_message
|
self._context["ak_message"] = self.expr_func_message
|
||||||
self._context["ip_address"] = ip_address
|
self._context["ip_address"] = ip_address
|
||||||
self._context["ip_network"] = ip_network
|
self._context["ip_network"] = ip_network
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load authentik_utils %}
|
{% load authentik_utils %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
{{ block.super }}
|
||||||
|
<style>
|
||||||
|
.pf-c-background-image::before {
|
||||||
|
background-image: url("{% static 'dist/assets/images/flow_background.jpg' %}");
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans 'End session' %}
|
{% trans 'End session' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -15,10 +15,11 @@ from authentik.core.models import User
|
|||||||
from authentik.flows.models import Flow, in_memory_stage
|
from authentik.flows.models import Flow, in_memory_stage
|
||||||
from authentik.flows.planner import (
|
from authentik.flows.planner import (
|
||||||
PLAN_CONTEXT_PENDING_USER,
|
PLAN_CONTEXT_PENDING_USER,
|
||||||
|
PLAN_CONTEXT_REDIRECT,
|
||||||
PLAN_CONTEXT_SSO,
|
PLAN_CONTEXT_SSO,
|
||||||
FlowPlanner,
|
FlowPlanner,
|
||||||
)
|
)
|
||||||
from authentik.flows.views import SESSION_KEY_PLAN
|
from authentik.flows.views import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
|
||||||
from authentik.lib.utils.urls import redirect_with_qs
|
from authentik.lib.utils.urls import redirect_with_qs
|
||||||
from authentik.policies.utils import delete_none_keys
|
from authentik.policies.utils import delete_none_keys
|
||||||
from authentik.sources.oauth.auth import AuthorizedServiceBackend
|
from authentik.sources.oauth.auth import AuthorizedServiceBackend
|
||||||
@ -135,11 +136,17 @@ class OAuthCallback(OAuthClientMixin, View):
|
|||||||
|
|
||||||
def handle_login_flow(self, flow: Flow, **kwargs) -> HttpResponse:
|
def handle_login_flow(self, flow: Flow, **kwargs) -> HttpResponse:
|
||||||
"""Prepare Authentication Plan, redirect user FlowExecutor"""
|
"""Prepare Authentication Plan, redirect user FlowExecutor"""
|
||||||
|
# Ensure redirect is carried through when user was trying to
|
||||||
|
# authorize application
|
||||||
|
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
|
||||||
|
NEXT_ARG_NAME, "authentik_core:shell"
|
||||||
|
)
|
||||||
kwargs.update(
|
kwargs.update(
|
||||||
{
|
{
|
||||||
# Since we authenticate the user by their token, they have no backend set
|
# Since we authenticate the user by their token, they have no backend set
|
||||||
PLAN_CONTEXT_AUTHENTICATION_BACKEND: "django.contrib.auth.backends.ModelBackend",
|
PLAN_CONTEXT_AUTHENTICATION_BACKEND: "django.contrib.auth.backends.ModelBackend",
|
||||||
PLAN_CONTEXT_SSO: True,
|
PLAN_CONTEXT_SSO: True,
|
||||||
|
PLAN_CONTEXT_REDIRECT: final_redirect,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# We run the Flow planner here so we can pass the Pending user in the context
|
# We run the Flow planner here so we can pass the Pending user in the context
|
||||||
|
@ -13,10 +13,11 @@ from authentik.core.models import User
|
|||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
from authentik.flows.planner import (
|
from authentik.flows.planner import (
|
||||||
PLAN_CONTEXT_PENDING_USER,
|
PLAN_CONTEXT_PENDING_USER,
|
||||||
|
PLAN_CONTEXT_REDIRECT,
|
||||||
PLAN_CONTEXT_SSO,
|
PLAN_CONTEXT_SSO,
|
||||||
FlowPlanner,
|
FlowPlanner,
|
||||||
)
|
)
|
||||||
from authentik.flows.views import SESSION_KEY_PLAN
|
from authentik.flows.views import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
|
||||||
from authentik.lib.utils.urls import redirect_with_qs
|
from authentik.lib.utils.urls import redirect_with_qs
|
||||||
from authentik.policies.utils import delete_none_keys
|
from authentik.policies.utils import delete_none_keys
|
||||||
from authentik.sources.saml.exceptions import (
|
from authentik.sources.saml.exceptions import (
|
||||||
@ -54,11 +55,14 @@ class ResponseProcessor:
|
|||||||
_root: Any
|
_root: Any
|
||||||
_root_xml: str
|
_root_xml: str
|
||||||
|
|
||||||
|
_http_request: HttpRequest
|
||||||
|
|
||||||
def __init__(self, source: SAMLSource):
|
def __init__(self, source: SAMLSource):
|
||||||
self._source = source
|
self._source = source
|
||||||
|
|
||||||
def parse(self, request: HttpRequest):
|
def parse(self, request: HttpRequest):
|
||||||
"""Check if `request` contains SAML Response data, parse and validate it."""
|
"""Check if `request` contains SAML Response data, parse and validate it."""
|
||||||
|
self._http_request = request
|
||||||
# First off, check if we have any SAML Data at all.
|
# First off, check if we have any SAML Data at all.
|
||||||
raw_response = request.POST.get("SAMLResponse", None)
|
raw_response = request.POST.get("SAMLResponse", None)
|
||||||
if not raw_response:
|
if not raw_response:
|
||||||
@ -187,6 +191,11 @@ class ResponseProcessor:
|
|||||||
|
|
||||||
name_id_filter = self._get_name_id_filter()
|
name_id_filter = self._get_name_id_filter()
|
||||||
matching_users = User.objects.filter(**name_id_filter)
|
matching_users = User.objects.filter(**name_id_filter)
|
||||||
|
# Ensure redirect is carried through when user was trying to
|
||||||
|
# authorize application
|
||||||
|
final_redirect = self._http_request.session.get(SESSION_KEY_GET, {}).get(
|
||||||
|
NEXT_ARG_NAME, "authentik_core:shell"
|
||||||
|
)
|
||||||
if matching_users.exists():
|
if matching_users.exists():
|
||||||
# User exists already, switch to authentication flow
|
# User exists already, switch to authentication flow
|
||||||
return self._flow_response(
|
return self._flow_response(
|
||||||
@ -195,6 +204,7 @@ class ResponseProcessor:
|
|||||||
**{
|
**{
|
||||||
PLAN_CONTEXT_PENDING_USER: matching_users.first(),
|
PLAN_CONTEXT_PENDING_USER: matching_users.first(),
|
||||||
PLAN_CONTEXT_AUTHENTICATION_BACKEND: DEFAULT_BACKEND,
|
PLAN_CONTEXT_AUTHENTICATION_BACKEND: DEFAULT_BACKEND,
|
||||||
|
PLAN_CONTEXT_REDIRECT: final_redirect,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return self._flow_response(
|
return self._flow_response(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
"""authentik flows invitation forms"""
|
"""authentik flows invitation forms"""
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
from authentik.admin.fields import CodeMirrorWidget, YAMLField
|
from authentik.admin.fields import CodeMirrorWidget, YAMLField
|
||||||
from authentik.stages.invitation.models import Invitation, InvitationStage
|
from authentik.stages.invitation.models import Invitation, InvitationStage
|
||||||
@ -25,8 +24,5 @@ class InvitationForm(forms.ModelForm):
|
|||||||
|
|
||||||
model = Invitation
|
model = Invitation
|
||||||
fields = ["expires", "fixed_data"]
|
fields = ["expires", "fixed_data"]
|
||||||
labels = {
|
|
||||||
"fixed_data": _("Optional fixed data to enforce on user enrollment."),
|
|
||||||
}
|
|
||||||
widgets = {"fixed_data": CodeMirrorWidget()}
|
widgets = {"fixed_data": CodeMirrorWidget()}
|
||||||
field_classes = {"fixed_data": YAMLField}
|
field_classes = {"fixed_data": YAMLField}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.1.4 on 2020-12-25 21:43
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_stages_invitation", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="invitation",
|
||||||
|
name="fixed_data",
|
||||||
|
field=models.JSONField(blank=True, default=dict),
|
||||||
|
),
|
||||||
|
]
|
@ -61,7 +61,11 @@ class Invitation(models.Model):
|
|||||||
|
|
||||||
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
expires = models.DateTimeField(default=None, blank=True, null=True)
|
expires = models.DateTimeField(default=None, blank=True, null=True)
|
||||||
fixed_data = models.JSONField(default=dict)
|
fixed_data = models.JSONField(
|
||||||
|
default=dict,
|
||||||
|
blank=True,
|
||||||
|
help_text=_("Optional fixed data to enforce on user enrollment."),
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Invitation {self.invite_uuid.hex} created by {self.created_by}"
|
return f"Invitation {self.invite_uuid.hex} created by {self.created_by}"
|
||||||
|
@ -53,5 +53,5 @@ class PasswordStageForm(forms.ModelForm):
|
|||||||
fields = ["name", "backends", "configure_flow", "failed_attempts_before_cancel"]
|
fields = ["name", "backends", "configure_flow", "failed_attempts_before_cancel"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"name": forms.TextInput(),
|
"name": forms.TextInput(),
|
||||||
"backends": forms.SelectMultiple(get_authentication_backends()),
|
"backends": forms.SelectMultiple(choices=get_authentication_backends()),
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
server:
|
server:
|
||||||
image: beryju/authentik:${AUTHENTIK_TAG:-0.13.2-stable}
|
image: beryju/authentik:${AUTHENTIK_TAG:-0.13.5-stable}
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
AUTHENTIK_REDIS__HOST: redis
|
AUTHENTIK_REDIS__HOST: redis
|
||||||
@ -44,7 +44,7 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
worker:
|
worker:
|
||||||
image: beryju/authentik:${AUTHENTIK_TAG:-0.13.2-stable}
|
image: beryju/authentik:${AUTHENTIK_TAG:-0.13.5-stable}
|
||||||
command: worker
|
command: worker
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
@ -60,7 +60,7 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
static:
|
static:
|
||||||
image: beryju/authentik-static:${AUTHENTIK_TAG:-0.13.2-stable}
|
image: beryju/authentik-static:${AUTHENTIK_TAG:-0.13.5-stable}
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
labels:
|
labels:
|
||||||
|
@ -4,7 +4,7 @@ name: authentik
|
|||||||
home: https://goauthentik.io
|
home: https://goauthentik.io
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/BeryJu/authentik
|
- https://github.com/BeryJu/authentik
|
||||||
version: "0.13.2-stable"
|
version: "0.13.5-stable"
|
||||||
icon: https://raw.githubusercontent.com/BeryJu/authentik/master/web/icons/icon.svg
|
icon: https://raw.githubusercontent.com/BeryJu/authentik/master/web/icons/icon.svg
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: postgresql
|
- name: postgresql
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|-----------------------------------|-------------------------|-------------|
|
|-----------------------------------|-------------------------|-------------|
|
||||||
| image.name | beryju/authentik | Image used to run the authentik server and worker |
|
| image.name | beryju/authentik | Image used to run the authentik server and worker |
|
||||||
| image.name_static | beryju/authentik-static | Image used to run the authentik static server (CSS and JS Files) |
|
| image.name_static | beryju/authentik-static | Image used to run the authentik static server (CSS and JS Files) |
|
||||||
| image.tag | 0.13.2-stable | Image tag |
|
| image.tag | 0.13.5-stable | Image tag |
|
||||||
| image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments |
|
| image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments |
|
||||||
| serverReplicas | 1 | Replicas for the Server deployment |
|
| serverReplicas | 1 | Replicas for the Server deployment |
|
||||||
| workerReplicas | 1 | Replicas for the Worker deployment |
|
| workerReplicas | 1 | Replicas for the Worker deployment |
|
||||||
|
@ -5,7 +5,7 @@ image:
|
|||||||
name: beryju/authentik
|
name: beryju/authentik
|
||||||
name_static: beryju/authentik-static
|
name_static: beryju/authentik-static
|
||||||
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
|
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
|
||||||
tag: 0.13.2-stable
|
tag: 0.13.5-stable
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
serverReplicas: 1
|
serverReplicas: 1
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
const VERSION = "0.13.2-stable"
|
const VERSION = "0.13.5-stable"
|
||||||
|
@ -7345,7 +7345,6 @@ definitions:
|
|||||||
description: KubernetesServiceConnection Serializer
|
description: KubernetesServiceConnection Serializer
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
- kubeconfig
|
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
pk:
|
pk:
|
||||||
@ -8596,6 +8595,7 @@ definitions:
|
|||||||
x-nullable: true
|
x-nullable: true
|
||||||
fixed_data:
|
fixed_data:
|
||||||
title: Fixed data
|
title: Fixed data
|
||||||
|
description: Optional fixed data to enforce on user enrollment.
|
||||||
type: object
|
type: object
|
||||||
OTPStaticStage:
|
OTPStaticStage:
|
||||||
description: OTPStaticStage Serializer
|
description: OTPStaticStage Serializer
|
||||||
|
108
web/package-lock.json
generated
108
web/package-lock.json
generated
@ -142,13 +142,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/browser": {
|
"@sentry/browser": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.29.2.tgz",
|
||||||
"integrity": "sha512-cVlXoQBJ64eNNkQuOB+bS6sK5KWV+Fw+ZYxT+XqjpeXkOPaxh8aeoi9CHz2DsFfbLV91P4AnXZEUdDl+7ktQNg==",
|
"integrity": "sha512-uxZ7y7rp85tJll+RZtXRhXPbnFnOaxZqJEv05vJlXBtBNLQtlczV5iCtU9mZRLVHDtmZ5VVKUV8IKXntEqqDpQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/core": "5.29.1",
|
"@sentry/core": "5.29.2",
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"@sentry/utils": "5.29.1",
|
"@sentry/utils": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -160,14 +160,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/core": {
|
"@sentry/core": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.29.2.tgz",
|
||||||
"integrity": "sha512-SMybIx9IlswkJ7a61ez/zjdiMdAo51Adpo4nVrzke2k84U/t726/EbJj0FJ4vVgsGdLCvSSZ6v7BQlINcwWupg==",
|
"integrity": "sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "5.29.1",
|
"@sentry/hub": "5.29.2",
|
||||||
"@sentry/minimal": "5.29.1",
|
"@sentry/minimal": "5.29.2",
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"@sentry/utils": "5.29.1",
|
"@sentry/utils": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -179,12 +179,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/hub": {
|
"@sentry/hub": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.29.2.tgz",
|
||||||
"integrity": "sha512-Ig/vqCiJcsnGaWajkWRFH+5IKeo50ZtsjM0zJb8IfTadLjQuF/gTQst0aXO3l6q4HzveeGsELY8jlm6WVcq9Aw==",
|
"integrity": "sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"@sentry/utils": "5.29.1",
|
"@sentry/utils": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -196,12 +196,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/minimal": {
|
"@sentry/minimal": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.29.2.tgz",
|
||||||
"integrity": "sha512-lAa3+Duxum1qQvR0tKiBUsH6Ehit3g/vO53SqBib7YK3qdvIUWHacmkJvfz/AeSvVnpJ9bsBMCVRJNSVe8BPVA==",
|
"integrity": "sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "5.29.1",
|
"@sentry/hub": "5.29.2",
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -213,17 +213,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/tracing": {
|
"@sentry/tracing": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.29.2.tgz",
|
||||||
"integrity": "sha512-iWfPtDhf5X7N9R5WB3vX/wlyFVsGG8iMx4hLIP+6bj8EcPYnZfeP6Sxn65a0ACT/FKv7SMBoZ1qPDzmvk0bviw==",
|
"integrity": "sha512-iumYbVRpvoU3BUuIooxibydeaOOjl5ysc+mzsqhRs2NGW/C3uKAsFXdvyNfqt3bxtRQwJEhwJByLP2u3pLThpw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "5.29.1",
|
"@sentry/hub": "5.29.2",
|
||||||
"@sentry/minimal": "5.29.1",
|
"@sentry/minimal": "5.29.2",
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"@sentry/utils": "5.29.1",
|
"@sentry/utils": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@sentry/hub": {
|
||||||
|
"version": "5.29.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.29.2.tgz",
|
||||||
|
"integrity": "sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "5.29.2",
|
||||||
|
"@sentry/utils": "5.29.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/minimal": {
|
||||||
|
"version": "5.29.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.29.2.tgz",
|
||||||
|
"integrity": "sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/hub": "5.29.2",
|
||||||
|
"@sentry/types": "5.29.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/types": {
|
||||||
|
"version": "5.29.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.29.2.tgz",
|
||||||
|
"integrity": "sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA=="
|
||||||
|
},
|
||||||
|
"@sentry/utils": {
|
||||||
|
"version": "5.29.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.29.2.tgz",
|
||||||
|
"integrity": "sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "5.29.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
@ -232,16 +266,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/types": {
|
"@sentry/types": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.29.2.tgz",
|
||||||
"integrity": "sha512-QXZBA1gJheMYTGFV+UUhr3+jKpGZqPx8kEJABs8htlKabCDJlEeoFNmeqPuVxCxukoy5ZaaHACoE+2Z87T0g2A=="
|
"integrity": "sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA=="
|
||||||
},
|
},
|
||||||
"@sentry/utils": {
|
"@sentry/utils": {
|
||||||
"version": "5.29.1",
|
"version": "5.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.29.2.tgz",
|
||||||
"integrity": "sha512-FOhWxASvIQREAlSuWf3Vmb4uIkG0fmRdHkULpuv5dFmrMX2PpudYAppQtS8K9V4BYxFy6KFdUht1Qz5zYTecMw==",
|
"integrity": "sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/types": "5.29.1",
|
"@sentry/types": "5.29.2",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.15.1",
|
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||||
"@patternfly/patternfly": "^4.70.2",
|
"@patternfly/patternfly": "^4.70.2",
|
||||||
"@sentry/browser": "^5.29.1",
|
"@sentry/browser": "^5.29.2",
|
||||||
"@sentry/tracing": "^5.29.1",
|
"@sentry/tracing": "^5.29.2",
|
||||||
"@types/chart.js": "^2.9.29",
|
"@types/chart.js": "^2.9.29",
|
||||||
"@types/codemirror": "0.0.102",
|
"@types/codemirror": "0.0.102",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
|
@ -5,11 +5,6 @@ html {
|
|||||||
--pf-c-nav__link--PaddingLeft: 0.5rem;
|
--pf-c-nav__link--PaddingLeft: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix patternfly sidebar and header with open Modal */
|
|
||||||
.pf-c-page__sidebar {
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pf-c-page__header {
|
.pf-c-page__header {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
@ -86,6 +81,10 @@ select[multiple] {
|
|||||||
font-size: var(--pf-global--FontSize--sm);
|
font-size: var(--pf-global--FontSize--sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pf-c-page__main {
|
||||||
|
z-index: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
:root {
|
||||||
--ak-dark-foreground: #fafafa;
|
--ak-dark-foreground: #fafafa;
|
||||||
|
@ -28,4 +28,4 @@ export const ColorStyles = css`
|
|||||||
background-color: var(--pf-global--danger-color--100);
|
background-color: var(--pf-global--danger-color--100);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export const VERSION = "0.13.2-stable";
|
export const VERSION = "0.13.5-stable";
|
||||||
|
35
web/src/elements/sidebar/SidebarHamburger.ts
Normal file
35
web/src/elements/sidebar/SidebarHamburger.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { css, CSSResult, customElement, html, LitElement, TemplateResult } from "lit-element";
|
||||||
|
import { COMMON_STYLES } from "../../common/styles";
|
||||||
|
|
||||||
|
@customElement("ak-sidebar-hamburger")
|
||||||
|
export class SidebarHamburger extends LitElement {
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return COMMON_STYLES.concat(
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
position: absolute;
|
||||||
|
top: var(--pf-c-page__main-section--PaddingTop);
|
||||||
|
right: var(--pf-c-page__main-section--PaddingRight);
|
||||||
|
z-index: 250;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(): void {
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent("ak-sidebar-toggle", {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): TemplateResult {
|
||||||
|
return html`<button @click=${() => (this.onClick())} class="pf-c-button pf-m-plain" type="button">
|
||||||
|
<i class="fas fa-bars" aria-hidden="true"></i>
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
import { gettext } from "django";
|
import { gettext } from "django";
|
||||||
import { html, LitElement, TemplateResult } from "lit-element";
|
import { html, LitElement, property, TemplateResult } from "lit-element";
|
||||||
import { SidebarItem } from "../elements/sidebar/Sidebar";
|
import { SidebarItem } from "../elements/sidebar/Sidebar";
|
||||||
|
|
||||||
import "../elements/router/RouterOutlet";
|
import "../elements/router/RouterOutlet";
|
||||||
import "../elements/messages/MessageContainer";
|
import "../elements/messages/MessageContainer";
|
||||||
|
import "../elements/sidebar/SidebarHamburger";
|
||||||
|
|
||||||
export abstract class Interface extends LitElement {
|
export abstract class Interface extends LitElement {
|
||||||
|
@property({type: Boolean})
|
||||||
|
sidebarOpen?: boolean;
|
||||||
|
|
||||||
abstract get sidebar(): SidebarItem[];
|
abstract get sidebar(): SidebarItem[];
|
||||||
|
|
||||||
@ -13,11 +16,24 @@ export abstract class Interface extends LitElement {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.sidebarOpen = window.outerWidth >= 1280;
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
this.sidebarOpen = window.outerWidth >= 1280;
|
||||||
|
});
|
||||||
|
window.addEventListener("ak-sidebar-toggle", () => {
|
||||||
|
this.sidebarOpen = !this.sidebarOpen;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
return html`<ak-message-container></ak-message-container>
|
return html`<ak-message-container></ak-message-container>
|
||||||
<div class="pf-c-page">
|
<div class="pf-c-page">
|
||||||
<a class="pf-c-skip-to-content pf-c-button pf-m-primary" href="#main-content">${gettext("Skip to content")}</a>
|
<a class="pf-c-skip-to-content pf-c-button pf-m-primary" href="#main-content">${gettext("Skip to content")}</a>
|
||||||
<ak-sidebar class="pf-c-page__sidebar" .items=${this.sidebar}>
|
<ak-sidebar-hamburger>
|
||||||
|
</ak-sidebar-hamburger>
|
||||||
|
<ak-sidebar class="pf-c-page__sidebar ${this.sidebarOpen ? "pf-m-expanded" : "pf-m-collapsed"}" .items=${this.sidebar}>
|
||||||
</ak-sidebar>
|
</ak-sidebar>
|
||||||
<main class="pf-c-page__main">
|
<main class="pf-c-page__main">
|
||||||
<ak-router-outlet role="main" class="pf-c-page__main" tabindex="-1" id="main-content" defaultUrl="/library/">
|
<ak-router-outlet role="main" class="pf-c-page__main" tabindex="-1" id="main-content" defaultUrl="/library/">
|
||||||
|
@ -15,7 +15,7 @@ Download the latest `docker-compose.yml` from [here](https://raw.githubuserconte
|
|||||||
|
|
||||||
To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env`
|
To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env`
|
||||||
|
|
||||||
To optionally deploy a different version run `echo AUTHENTIK_TAG=0.13.2-stable >> .env`
|
To optionally deploy a different version run `echo AUTHENTIK_TAG=0.13.5-stable >> .env`
|
||||||
|
|
||||||
If this is a fresh authentik install run the following commands to generate a password:
|
If this is a fresh authentik install run the following commands to generate a password:
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ image:
|
|||||||
name: beryju/authentik
|
name: beryju/authentik
|
||||||
name_static: beryju/authentik-static
|
name_static: beryju/authentik-static
|
||||||
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
|
name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended
|
||||||
tag: 0.13.2-stable
|
tag: 0.13.5-stable
|
||||||
|
|
||||||
serverReplicas: 1
|
serverReplicas: 1
|
||||||
workerReplicas: 1
|
workerReplicas: 1
|
||||||
|
Reference in New Issue
Block a user