cleanup
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
86b69e83e0
commit
ccb2d0aaed
|
@ -1,12 +1,10 @@
|
||||||
"""AuthenticatorDuoStage API Views"""
|
"""AuthenticatorMobileStage API Views"""
|
||||||
from django.http import Http404
|
|
||||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
from drf_spectacular.utils import extend_schema, inline_serializer
|
||||||
from guardian.shortcuts import get_objects_for_user
|
|
||||||
from rest_framework import mixins
|
from rest_framework import mixins
|
||||||
from rest_framework.decorators import action
|
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.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.permissions import IsAdminUser
|
from rest_framework.permissions import IsAdminUser
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
@ -15,7 +13,6 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
from authentik.api.decorators import permission_required
|
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.authenticator_mobile.models import AuthenticatorMobileStage, MobileDevice
|
from authentik.stages.authenticator_mobile.models import AuthenticatorMobileStage, MobileDevice
|
||||||
|
|
|
@ -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
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import authentik.core.models
|
||||||
|
import authentik.stages.authenticator_mobile.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
@ -85,4 +88,43 @@ class Migration(migrations.Migration):
|
||||||
"verbose_name_plural": "Mobile Devices",
|
"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,
|
||||||
|
},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,8 +7,8 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django_otp.models import Device
|
from django_otp.models import Device
|
||||||
from rest_framework.serializers import BaseSerializer, Serializer
|
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.core.types import UserSettingSerializer
|
||||||
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
|
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
|
@ -21,7 +21,7 @@ def default_token_key():
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorMobileStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
class AuthenticatorMobileStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
||||||
"""Setup Duo authenticator devices"""
|
"""Setup Mobile authenticator devices"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> type[BaseSerializer]:
|
def serializer(self) -> type[BaseSerializer]:
|
||||||
|
@ -78,8 +78,8 @@ class MobileDevice(SerializerModel, Device):
|
||||||
verbose_name = _("Mobile Device")
|
verbose_name = _("Mobile Device")
|
||||||
verbose_name_plural = _("Mobile Devices")
|
verbose_name_plural = _("Mobile Devices")
|
||||||
|
|
||||||
class MobileDeviceToken(ExpiringModel):
|
|
||||||
|
|
||||||
|
class MobileDeviceToken(ExpiringModel):
|
||||||
device = models.ForeignKey(MobileDevice, on_delete=models.CASCADE, null=True)
|
device = models.ForeignKey(MobileDevice, on_delete=models.CASCADE, null=True)
|
||||||
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
||||||
token = models.TextField(default=default_token_key)
|
token = models.TextField(default=default_token_key)
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
"""Mobile stage"""
|
"""Mobile stage"""
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.utils.timezone import now
|
|
||||||
from rest_framework.fields import CharField
|
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 (
|
from authentik.flows.challenge import (
|
||||||
Challenge,
|
Challenge,
|
||||||
ChallengeResponse,
|
ChallengeResponse,
|
||||||
|
@ -24,6 +22,7 @@ class AuthenticatorMobilePayloadChallenge(PassiveSerializer):
|
||||||
s = CharField(required=False, help_text="Stage UUID")
|
s = CharField(required=False, help_text="Stage UUID")
|
||||||
t = CharField(required=False, help_text="Initial Token")
|
t = CharField(required=False, help_text="Initial Token")
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorMobileChallenge(WithUserInfoChallenge):
|
class AuthenticatorMobileChallenge(WithUserInfoChallenge):
|
||||||
"""Mobile Challenge"""
|
"""Mobile Challenge"""
|
||||||
|
|
||||||
|
@ -53,12 +52,14 @@ class AuthenticatorMobileStageView(ChallengeStageView):
|
||||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||||
stage: AuthenticatorMobileStage = self.executor.current_stage
|
stage: AuthenticatorMobileStage = self.executor.current_stage
|
||||||
self.prepare()
|
self.prepare()
|
||||||
payload = AuthenticatorMobilePayloadChallenge(data={
|
payload = AuthenticatorMobilePayloadChallenge(
|
||||||
# TODO: use cloud gateway?
|
data={
|
||||||
"u": self.request.get_host(),
|
# TODO: use cloud gateway?
|
||||||
"s": str(stage.stage_uuid),
|
"u": self.request.get_host(),
|
||||||
"t": self.executor.plan[FLOW_PLAN_MOBILE_ENROLL].token,
|
"s": str(stage.stage_uuid),
|
||||||
})
|
"t": self.executor.plan[FLOW_PLAN_MOBILE_ENROLL].token,
|
||||||
|
}
|
||||||
|
)
|
||||||
payload.is_valid()
|
payload.is_valid()
|
||||||
return AuthenticatorMobileChallenge(
|
return AuthenticatorMobileChallenge(
|
||||||
data={
|
data={
|
||||||
|
|
Reference in New Issue