Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2023-07-24 23:34:00 +02:00
parent b177d14e50
commit 1a392275d4
No known key found for this signature in database
4 changed files with 59 additions and 19 deletions

View File

@ -1,12 +1,10 @@
"""AuthenticatorDuoStage API Views"""
from django.http import Http404
"""AuthenticatorMobileStage API Views"""
from django_filters.rest_framework.backends import DjangoFilterBackend
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
from guardian.shortcuts import get_objects_for_user
from drf_spectacular.utils import extend_schema, inline_serializer
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.fields import CharField, ChoiceField, IntegerField
from rest_framework.fields import CharField
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.request import Request
@ -15,7 +13,6 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.api.decorators import permission_required
from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_mobile.models import AuthenticatorMobileStage, MobileDevice

View File

@ -1,9 +1,12 @@
# Generated by Django 4.1.10 on 2023-07-24 18:48
# Generated by Django 4.1.10 on 2023-07-24 21:33
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import authentik.core.models
import authentik.stages.authenticator_mobile.models
class Migration(migrations.Migration):
initial = True
@ -85,4 +88,43 @@ class Migration(migrations.Migration):
"verbose_name_plural": "Mobile Devices",
},
),
migrations.CreateModel(
name="MobileDeviceToken",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"expires",
models.DateTimeField(default=authentik.core.models.default_token_duration),
),
("expiring", models.BooleanField(default=True)),
(
"token",
models.TextField(
default=authentik.stages.authenticator_mobile.models.default_token_key
),
),
(
"device",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="authentik_stages_authenticator_mobile.mobiledevice",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
"abstract": False,
},
),
]

View File

@ -7,8 +7,8 @@ from django.utils.translation import gettext_lazy as _
from django.views import View
from django_otp.models import Device
from rest_framework.serializers import BaseSerializer, Serializer
from authentik.core.models import ExpiringModel
from authentik.core.models import ExpiringModel
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
from authentik.lib.generators import generate_id
@ -21,7 +21,7 @@ def default_token_key():
class AuthenticatorMobileStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Setup Duo authenticator devices"""
"""Setup Mobile authenticator devices"""
@property
def serializer(self) -> type[BaseSerializer]:
@ -78,8 +78,8 @@ class MobileDevice(SerializerModel, Device):
verbose_name = _("Mobile Device")
verbose_name_plural = _("Mobile Devices")
class MobileDeviceToken(ExpiringModel):
class MobileDeviceToken(ExpiringModel):
device = models.ForeignKey(MobileDevice, on_delete=models.CASCADE, null=True)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
token = models.TextField(default=default_token_key)

View File

@ -1,10 +1,8 @@
"""Mobile stage"""
from django.http import HttpResponse
from django.utils.timezone import now
from rest_framework.fields import CharField
from authentik.core.api.utils import PassiveSerializer
from authentik.events.models import Event, EventAction
from authentik.core.api.utils import PassiveSerializer
from authentik.flows.challenge import (
Challenge,
ChallengeResponse,
@ -24,6 +22,7 @@ class AuthenticatorMobilePayloadChallenge(PassiveSerializer):
s = CharField(required=False, help_text="Stage UUID")
t = CharField(required=False, help_text="Initial Token")
class AuthenticatorMobileChallenge(WithUserInfoChallenge):
"""Mobile Challenge"""
@ -53,12 +52,14 @@ class AuthenticatorMobileStageView(ChallengeStageView):
def get_challenge(self, *args, **kwargs) -> Challenge:
stage: AuthenticatorMobileStage = self.executor.current_stage
self.prepare()
payload = AuthenticatorMobilePayloadChallenge(data={
payload = AuthenticatorMobilePayloadChallenge(
data={
# TODO: use cloud gateway?
"u": self.request.get_host(),
"s": str(stage.stage_uuid),
"t": self.executor.plan[FLOW_PLAN_MOBILE_ENROLL].token,
})
}
)
payload.is_valid()
return AuthenticatorMobileChallenge(
data={