-
-
Notifications
You must be signed in to change notification settings - Fork 889
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jens Langhammer <[email protected]>
- Loading branch information
Showing
21 changed files
with
1,609 additions
and
13,617 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
authentik/enterprise/stages/authenticator_endpoint_gdtc/api.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
"""AuthenticatorEndpointGDTCStage API Views""" | ||
|
||
from django_filters.rest_framework.backends import DjangoFilterBackend | ||
from rest_framework import mixins | ||
from rest_framework.filters import OrderingFilter, SearchFilter | ||
from rest_framework.permissions import IsAdminUser | ||
from rest_framework.serializers import ModelSerializer | ||
from rest_framework.viewsets import GenericViewSet, ModelViewSet | ||
from structlog.stdlib import get_logger | ||
|
||
from authentik.api.authorization import OwnerFilter, OwnerPermissions | ||
from authentik.core.api.used_by import UsedByMixin | ||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import ( | ||
AuthenticatorEndpointGDTCStage, | ||
EndpointDevice, | ||
) | ||
from authentik.flows.api.stages import StageSerializer | ||
|
||
LOGGER = get_logger() | ||
|
||
|
||
class AuthenticatorEndpointGDTCStageSerializer(StageSerializer): | ||
"""AuthenticatorEndpointGDTCStage Serializer""" | ||
|
||
class Meta: | ||
model = AuthenticatorEndpointGDTCStage | ||
fields = StageSerializer.Meta.fields + [ | ||
"configure_flow", | ||
"friendly_name", | ||
"credentials", | ||
] | ||
|
||
|
||
class AuthenticatorEndpointGDTCStageViewSet(UsedByMixin, ModelViewSet): | ||
"""AuthenticatorEndpointGDTCStage Viewset""" | ||
|
||
queryset = AuthenticatorEndpointGDTCStage.objects.all() | ||
serializer_class = AuthenticatorEndpointGDTCStageSerializer | ||
filterset_fields = [ | ||
"name", | ||
"configure_flow", | ||
] | ||
search_fields = ["name"] | ||
ordering = ["name"] | ||
|
||
|
||
class EndpointDeviceSerializer(ModelSerializer): | ||
"""Serializer for Endpoint authenticator devices""" | ||
|
||
class Meta: | ||
model = EndpointDevice | ||
fields = ["pk", "name"] | ||
depth = 2 | ||
|
||
|
||
class EndpointDeviceViewSet( | ||
mixins.RetrieveModelMixin, | ||
mixins.UpdateModelMixin, | ||
mixins.DestroyModelMixin, | ||
UsedByMixin, | ||
mixins.ListModelMixin, | ||
GenericViewSet, | ||
): | ||
"""Viewset for Endpoint authenticator devices""" | ||
|
||
queryset = EndpointDevice.objects.all() | ||
serializer_class = EndpointDeviceSerializer | ||
search_fields = ["name"] | ||
filterset_fields = ["name"] | ||
ordering = ["name"] | ||
permission_classes = [OwnerPermissions] | ||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter] | ||
|
||
|
||
class EndpointAdminDeviceViewSet(ModelViewSet): | ||
"""Viewset for Endpoint authenticator devices (for admins)""" | ||
|
||
permission_classes = [IsAdminUser] | ||
queryset = EndpointDevice.objects.all() | ||
serializer_class = EndpointDeviceSerializer | ||
search_fields = ["name"] | ||
filterset_fields = ["name"] | ||
ordering = ["name"] |
13 changes: 13 additions & 0 deletions
13
authentik/enterprise/stages/authenticator_endpoint_gdtc/apps.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
"""authentik Endpoint app config""" | ||
|
||
from authentik.enterprise.apps import EnterpriseConfig | ||
|
||
|
||
class AuthentikStageAuthenticatorEndpointConfig(EnterpriseConfig): | ||
"""authentik endpoint config""" | ||
|
||
name = "authentik.enterprise.stages.authenticator_endpoint_gdtc" | ||
label = "authentik_stages_authenticator_endpoint_gdtc" | ||
verbose_name = "authentik Enterprise.Stages.Authenticator.Endpoint GDTC" | ||
default = True | ||
mountpoint = "endpoint/gdtc/" |
115 changes: 115 additions & 0 deletions
115
authentik/enterprise/stages/authenticator_endpoint_gdtc/migrations/0001_initial.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# Generated by Django 5.0.9 on 2024-10-14 17:08 | ||
|
||
import django.db.models.deletion | ||
import uuid | ||
from django.conf import settings | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
("authentik_flows", "0027_auto_20231028_1424"), | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="AuthenticatorEndpointGDTCStage", | ||
fields=[ | ||
( | ||
"stage_ptr", | ||
models.OneToOneField( | ||
auto_created=True, | ||
on_delete=django.db.models.deletion.CASCADE, | ||
parent_link=True, | ||
primary_key=True, | ||
serialize=False, | ||
to="authentik_flows.stage", | ||
), | ||
), | ||
("friendly_name", models.TextField(null=True)), | ||
("credentials", models.JSONField()), | ||
( | ||
"configure_flow", | ||
models.ForeignKey( | ||
blank=True, | ||
help_text="Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.", | ||
null=True, | ||
on_delete=django.db.models.deletion.SET_NULL, | ||
to="authentik_flows.flow", | ||
), | ||
), | ||
], | ||
options={ | ||
"verbose_name": "Endpoint Authenticator Google Device Trust Connector Stage", | ||
"verbose_name_plural": "Endpoint Authenticator Google Device Trust Connector Stages", | ||
}, | ||
bases=("authentik_flows.stage", models.Model), | ||
), | ||
migrations.CreateModel( | ||
name="EndpointDevice", | ||
fields=[ | ||
("created", models.DateTimeField(auto_now_add=True)), | ||
("last_updated", models.DateTimeField(auto_now=True)), | ||
( | ||
"name", | ||
models.CharField( | ||
help_text="The human-readable name of this device.", max_length=64 | ||
), | ||
), | ||
( | ||
"confirmed", | ||
models.BooleanField(default=True, help_text="Is this device ready for use?"), | ||
), | ||
("last_used", models.DateTimeField(null=True)), | ||
("uuid", models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), | ||
( | ||
"host_identifier", | ||
models.TextField( | ||
help_text="A unique identifier for the endpoint device, usually the device serial number", | ||
unique=True, | ||
), | ||
), | ||
("hostname", models.TextField()), | ||
( | ||
"user", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL | ||
), | ||
), | ||
], | ||
options={ | ||
"verbose_name": "Endpoint Device", | ||
"verbose_name_plural": "Endpoint Devices", | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name="EndpointDeviceConnection", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID" | ||
), | ||
), | ||
("attributes", models.JSONField()), | ||
( | ||
"device", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
to="authentik_stages_authenticator_endpoint_gdtc.endpointdevice", | ||
), | ||
), | ||
( | ||
"stage", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
to="authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage", | ||
), | ||
), | ||
], | ||
), | ||
] |
Empty file.
102 changes: 102 additions & 0 deletions
102
authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
"""Endpoint stage""" | ||
|
||
from uuid import uuid4 | ||
|
||
from django.contrib.auth import get_user_model | ||
from django.db import models | ||
from django.utils.translation import gettext_lazy as _ | ||
from google.oauth2.service_account import Credentials | ||
from rest_framework.serializers import BaseSerializer, Serializer | ||
|
||
from authentik.core.types import UserSettingSerializer | ||
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage | ||
from authentik.flows.stage import StageView | ||
from authentik.lib.models import SerializerModel | ||
from authentik.stages.authenticator.models import Device | ||
|
||
|
||
class AuthenticatorEndpointGDTCStage(ConfigurableStage, FriendlyNamedStage, Stage): | ||
"""Setup Google Chrome Device-trust connection""" | ||
|
||
credentials = models.JSONField() | ||
|
||
def google_credentials(self): | ||
return { | ||
"credentials": Credentials.from_service_account_info( | ||
self.credentials, scopes=["https://www.googleapis.com/auth/verifiedaccess"] | ||
), | ||
} | ||
|
||
@property | ||
def serializer(self) -> type[BaseSerializer]: | ||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.api import ( | ||
AuthenticatorEndpointStageSerializer, | ||
) | ||
|
||
return AuthenticatorEndpointStageSerializer | ||
|
||
@property | ||
def view(self) -> type[StageView]: | ||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.stage import ( | ||
AuthenticatorEndpointStageView, | ||
) | ||
|
||
return AuthenticatorEndpointStageView | ||
|
||
@property | ||
def component(self) -> str: | ||
return "ak-stage-authenticator-endpoint-gdtc-form" | ||
|
||
def ui_user_settings(self) -> UserSettingSerializer | None: | ||
return UserSettingSerializer( | ||
data={ | ||
"title": self.friendly_name or str(self._meta.verbose_name), | ||
"component": "ak-user-settings-authenticator-endpoint", | ||
} | ||
) | ||
|
||
def __str__(self) -> str: | ||
return f"Endpoint Authenticator Google Device Trust Connector Stage {self.name}" | ||
|
||
class Meta: | ||
verbose_name = _("Endpoint Authenticator Google Device Trust Connector Stage") | ||
verbose_name_plural = _("Endpoint Authenticator Google Device Trust Connector Stages") | ||
|
||
|
||
class EndpointDevice(SerializerModel, Device): | ||
"""Endpoint Device for a single user""" | ||
|
||
uuid = models.UUIDField(primary_key=True, default=uuid4) | ||
host_identifier = models.TextField( | ||
unique=True, | ||
help_text="A unique identifier for the endpoint device, usually the device serial number", | ||
) | ||
|
||
hostname = models.TextField() | ||
|
||
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) | ||
|
||
@property | ||
def serializer(self) -> Serializer: | ||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.api import ( | ||
EndpointDeviceSerializer, | ||
) | ||
|
||
return EndpointDeviceSerializer | ||
|
||
def __str__(self): | ||
return str(self.name) or str(self.user_id) | ||
|
||
class Meta: | ||
verbose_name = _("Endpoint Device") | ||
verbose_name_plural = _("Endpoint Devices") | ||
|
||
|
||
class EndpointDeviceConnection(models.Model): | ||
device = models.ForeignKey(EndpointDevice, on_delete=models.CASCADE) | ||
stage = models.ForeignKey(AuthenticatorEndpointGDTCStage, on_delete=models.CASCADE) | ||
|
||
attributes = models.JSONField() | ||
|
||
def __str__(self) -> str: | ||
return f"Endpoint device connection {self.device_id} to {self.stage_id}" |
29 changes: 29 additions & 0 deletions
29
authentik/enterprise/stages/authenticator_endpoint_gdtc/stage.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from django.http import HttpResponse | ||
from django.urls import reverse | ||
|
||
from authentik.flows.challenge import ( | ||
Challenge, | ||
ChallengeResponse, | ||
FrameChallenge, | ||
FrameChallengeResponse, | ||
) | ||
from authentik.flows.stage import ChallengeStageView | ||
|
||
|
||
class AuthenticatorEndpointStageView(ChallengeStageView): | ||
"""Endpoint stage""" | ||
|
||
response_class = FrameChallengeResponse | ||
|
||
def get_challenge(self, *args, **kwargs) -> Challenge: | ||
return FrameChallenge( | ||
data={ | ||
"component": "xak-flow-frame", | ||
"url": self.request.build_absolute_uri( | ||
reverse("authentik_stages_authenticator_endpoint_gdtc:chrome") | ||
), | ||
} | ||
) | ||
|
||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse: | ||
return self.executor.stage_ok() | ||
9 changes: 9 additions & 0 deletions
9
...uthenticator_endpoint_gdtc/templates/stages/authenticator_endpoint/google_chrome_dtc.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<html> | ||
<script> | ||
window.parent.postMessage({ | ||
message: "submit", | ||
source: "goauthentik.io", | ||
context: "flow-executor" | ||
}); | ||
</script> | ||
</html> |
26 changes: 26 additions & 0 deletions
26
authentik/enterprise/stages/authenticator_endpoint_gdtc/urls.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
"""API URLs""" | ||
|
||
from django.urls import path | ||
|
||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.api import ( | ||
AuthenticatorEndpointGDTCStageViewSet, | ||
EndpointAdminDeviceViewSet, | ||
EndpointDeviceViewSet, | ||
) | ||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.views.google_chrome.dtc import ( | ||
GoogleChromeDeviceTrustConnector, | ||
) | ||
|
||
urlpatterns = [ | ||
path("chrome/", GoogleChromeDeviceTrustConnector.as_view(), name="chrome"), | ||
] | ||
|
||
api_urlpatterns = [ | ||
("authenticators/endpoint", EndpointDeviceViewSet), | ||
( | ||
"authenticators/admin/endpoint", | ||
EndpointAdminDeviceViewSet, | ||
"admin-endpointdevice", | ||
), | ||
("stages/authenticator/endpoint_gdtc", AuthenticatorEndpointGDTCStageViewSet), | ||
] |
Empty file.
Empty file.
Oops, something went wrong.